Walkthrough: Localizing a Visual Studio SharePoint Application

Localizing a SharePoint application is replacing its hard-coded strings with expressions and statements that retrieve localized string values from resource files. This walkthrough shows you how to localize all of the string elements of a SharePoint Web page application.

This walkthrough demonstrates the following tasks:

  • Localizing code.

  • Localizing ASPX markup.

  • Localizing a feature.

Prerequisites

You need the following components on the development computer to complete this walkthrough:

Knowledge of the following concepts is helpful, but not required, to complete the walkthrough:

Localizing SharePoint Code

Code in SharePoint applications often contains hard-coded strings for UI text. These strings can be localized by replacing them with calls to GetGlobalResourceObject. Start the walkthrough by modifying a Web part project.

To modify the Web part project

  1. Complete the procedures outlined in the topic, Walkthrough: Creating a Web Part for SharePoint.

  2. With the Web part project loaded in Visual Studio, add an Application Page project item to the Web part project. Use the default name, ApplicationPage1.aspx.

  3. Add a Resources File project item to the Web part project. Use the default name, Resource1.resx. The Resources File project item template is located under the language project item templates folder in the Add New Item dialog box.

    The resource file opens in the Resource Editor.

  4. In the Resource Editor, enter the following string IDs and values:

    String ID

    Value

    String1

    Path to Employee Data File

    String2

    Location of the XML file that contains employee data

    String3

    Show Managers Only

    String4

    Shows only employees that are managers

    String5

    Show All Employees

    String6

    Employee List

    String7

    Display Employee List

    String8

    Application Page

    String9

    My Application page description

  5. Make a copy of Resource1.resx by clicking its node in Solution Explorer and then clicking Copy on the Edit menu.

  6. Click the Web part node in Solution Explorer and then click Paste on the Edit menu.

  7. Right-click the copied file and then click Rename. Name the file Resource1.ja-JP.resx.

    This file serves as the Japanese localized resource file that is later compiled into a satellite assembly and deployed to SharePoint.

  8. Open Resource1.ja-JP.resx into the Resource Editor and append the word JAPANESE in front of each value.

    For example, "Path to Employee Data File" becomes "JAPANESE Path to Employee Data File." In an actual localized scenario, these strings would use Japanese characters.

  9. Change the Deployment Type property of both Resource1.resx and Resource1.ja-JP.resx to AppGlobalResource.

    This causes the files to deploy to the App_GlobalResources folder on the server and makes the resources available to all ASP.NET-based projects.

    Not

    The Deployment Type property appears only for resource files added to SharePoint project items.

  10. Double-click Package.package to open it in the Package Designer.

  11. Click the Advanced button, click the Add button, and then click Add existing assembly.

    This opens the Add Existing Assembly dialog box.

  12. Build the project to create the localized satellite DLL.

  13. In the Add Existing Assembly dialog box, click the ellipsis (ASP.NET Mobile Designer ellipse) button next to Source Path and locate the localized Satellite DLL.

    The assembly file is located in your project directory under ..\bin\debug\ja-JP.

  14. Leave the Deployment Target option as GlobalAssemblyCache.

  15. In the Location box, prepend a culture ID folder to the Location path. For this example, change the existing value to jp-JA\Web part name.resources.dll. If your project has multiple satellite DLLs, repeat this step for each DLL.

    This step is necessary because a package does not allow two identically-named files in the same folder. Creating a subfolder based on the culture ID allows both files to be packaged together.

  16. When you are finished, click OK to close the dialog box.

  17. Open the code page for the Web part and replace the existing Using or Includes statements with the following.

    using Microsoft.SharePoint;
    using Microsoft.SharePoint.WebControls;
    using System;
    using System.ComponentModel;
    using System.Data;
    using System.Resources;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    
  18. Replace the existing variable declarations and functions with the following.

        private DataGrid grid;
            // Replaced: private static string verbText = "Show Managers Only";
            private static string verbText = HttpContext.GetGlobalResourceObject("Resource1", "String3").ToString();
            private Label errorMessage = new Label();
            protected string xmlFilePath;
    
            // Replaced: WedDisplayName and WebDescription attribute strings.
            [Personalizable(PersonalizationScope.Shared), WebBrowsable(true),
            LocalizedWebDisplayName("String1"),
            LocalizedWebDescription("String2")]
            public string DataFilePath
            {
                get
                {
                    return xmlFilePath;
                }
                set
                {
                    xmlFilePath = value;
                }
            }
    
            protected override void CreateChildControls()
            {
                // Define the grid control that displays employee data in the Web Part.
                grid = new DataGrid();
                grid.Width = Unit.Percentage(100);
                grid.GridLines = GridLines.Horizontal;
                grid.HeaderStyle.CssClass = "ms-vh2";
                grid.CellPadding = 2;
                grid.BorderWidth = Unit.Pixel(5);
                grid.HeaderStyle.Font.Bold = true;
                grid.HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
    
                // Populate the grid control with data in the employee data file.
                try
                {
                    DataSet dataset = new DataSet();
                    dataset.ReadXml(xmlFilePath, XmlReadMode.InferSchema);
                    grid.DataSource = dataset;
                    grid.DataBind();
                }
                catch (Exception x)
                {
                    errorMessage.Text += x.Message;
                }
    
                // Add control to the controls collection of the Web Part.
                Controls.Add(grid);
                Controls.Add(errorMessage);
                base.CreateChildControls();
            }
    
            public override WebPartVerbCollection Verbs
            {
                get
                {
                    WebPartVerb customVerb = new WebPartVerb("Manager_Filter_Verb",
                        new WebPartEventHandler(CustomVerbEventHandler));
    
                    customVerb.Text = verbText;
                    // Replaced: Hard-coded description with localized string.
                    customVerb.Description = HttpContext.GetGlobalResourceObject("Resource1", "String4").ToString();
                    WebPartVerb[] newVerbs = new WebPartVerb[] { customVerb };
    
                    return new WebPartVerbCollection(base.Verbs, newVerbs);
                }
            }
    
            protected void CustomVerbEventHandler(object sender, WebPartEventArgs args)
            {
                int titleColumn = 2;
    
                foreach (DataGridItem item in grid.Items)
                {
                    if (item.Cells[titleColumn].Text != "Manager")
                    {
                        if (item.Visible == true)
                        {
                            item.Visible = false;
                        }
                        else
                        {
                            item.Visible = true;
                        }
                    }
    
                }
                // if (verbText == "Show Managers Only")
                if (verbText == HttpContext.GetGlobalResourceObject("Resource1", "String5").ToString())
                {
                    // verbText = "Show All Employees";
                    verbText = HttpContext.GetGlobalResourceObject("Resource1", "String5").ToString();
                }
                else
                {
                    // verbText = "Show Managers Only";
                    verbText = HttpContext.GetGlobalResourceObject("Resource1", "String3").ToString();
                }
            }
    
  19. Add the following new functions.

    // Provide localized values for the WebDisplayName and WebDescription
    // attribute strings.
    public class LocalizedWebDisplayName : WebDisplayNameAttribute
    {
        public LocalizedWebDisplayName(string resId)
        {
            base.DisplayNameValue = FetchLocalizedString(resId);
        }
    
        string FetchLocalizedString(string resourceID)
        {
            // Use the ResourceManager to get the string from 
            // the resource file.
            ResourceManager rm = Resource1.ResourceManager;
            return rm.GetString(resourceID);
        }
    }
    
    public class LocalizedWebDescription : WebDescriptionAttribute
    {
        public LocalizedWebDescription(string resId)
        {
            base.DescriptionValue = FetchLocalizedString(resId);
        }
    
        string FetchLocalizedString(string resourceID)
        {
            // Use the ResourceManager to get the string from 
            // the resource file.
            ResourceManager rm = Resource1.ResourceManager;
            return rm.GetString(resourceID);
        }
    }
    
  20. Press F5 to build and run the solution.

  21. In SharePoint, click More Options on the Site Actions tab to display the Create dialog box.

  22. In the Create dialog box, click Page in the Filter By section, click Web Part Page in the installed items pane, and then click the Create button.

  23. In the New Web Part Page dialog box, enter a value in the Name box and then click the Create button.

  24. In the Web part page, click a Web part to display the tool bar.

  25. Click the Custom folder in the Categories section, select the Web part in the Web Parts section, and then click the Add button.

  26. Click the drop-down button for the Web part and then click Edit Web Part to display the Web part properties dialog box.

  27. Expand the Miscellaneous section, enter the path of the data.xml file, click Apply, and then click OK.

  28. After the data grid appears, click the drop-down button for the Web part again and notice that the custom verb displays in the default language.

  29. In the upper corner of the Web part page, click the drop-down arrow next to your name. If the language pack is successfully installed, there is a command called Select Display Language. Point to it and then click Japanese in the context menu. (If you installed a different language pack, that language choice displays here.)

    The text on the page appears in the selected language.

  30. Click the drop-down button for the Web part and then click Edit Web Part to display the Web part properties dialog box.

  31. Expand the Miscellaneous section and notice how all visible strings in the application appear in the localized language. The custom property box label, the tooltip for the control, and the verb all appear in the localized language.

  32. Switch the language back to the default and close the SharePoint page.

Localizing ASPX Markup

You can localize the markup in ASPX pages and controls by using resource files.

To localize ASPX Markup

  1. Double-click the application page to view its markup.

  2. Add a label and a button control to the application page by replacing the existing PlaceHolderMain section with the following:

    <asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
    <asp:Label ID="lbl" runat="server" Font-Size="Large" Text="<%$Resources:Resource1,String6%>"></asp:Label>
    <br />
    <br />
    <asp:Button ID="btn1" runat="server" onclick="btn1_Click" Text="<%$Resources:Resource1,String7%>"></asp:Button>
    </asp:Content>
    

    The hard-coded strings are replaced with the expression in the format <%$Resources:Resource File Name, Resource String ID%>. These expressions display the localized resource strings that are based on the current language.

  3. Replace the PageTitle and PageTitleInTitleArea sections with the following:

    <asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
    <asp:Literal ID="Literal1" runat="server" Text="<%$Resources:Resource1, String8%>" />
    </asp:Content>
    <asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >
    <asp:Literal ID="Literal2" runat="server" Text="<%$Resources:Resource1, String9%>" />
    </asp:Content>
    

    The hard-coded strings are replaced with the expression in the format <asp:literal ID="Literal1" runat="server" Text="<%$Resources:Resource File Name, String ID%>" />. These expressions display the localized resource strings that are based on the current language.

  4. Select the application page in Solution Explorer and then click Code on the View menu to display the code behind the application page.

  5. Add the following code.

    protected void btn1_Click(object sender, EventArgs e)
    {
        Response.Redirect("http://MyServer/MyPage.aspx", false);            
    }
    
  6. Press F5 to build and run the solution.

    The application page appears with default resource strings.

  7. In the upper corner of the application page, click the drop-down arrow next to your name and select the localized language.

    The text on the page appears with localized resource strings.

  8. Click the Display Employee List button to show the Web part page.

  9. Switch the language back to the default and close the SharePoint page.

Localizing Features

Features have a name and description that appears in SharePoint. You can localize these strings by using feature resource files. These resource files are separate from other resource files in the application.

To localize a feature

  1. Right-click the Feature1 node in Solution Explorer and then click Add Feature Resource.

  2. In the Add Resource dialog box, select the default culture, Invariant Language.

    This adds a file that is named Resources.resx to the feature that serves as the default feature resource. The resource file opens in the Resource Editor.

  3. In the Resource Editor, enter the following string IDs and values:

    String ID

    Value

    String1

    My Feature Title

    String2

    My feature description

  4. Add another feature resource file, but select a different culture, such as Japanese (Japan).

    This adds a file that is named Resources.ja-JP.rex to the feature. Because feature resources require a full culture identifier in their name, select the culture ID in the list that specifies the full culture. For example, select Japanese (Japan) instead of Japanese.

  5. Change the string values in the localized resource file to something different than those in the default feature resource file.

  6. Double-click the Feature1.feature file to open it in the Feature Designer.

  7. Replace the text in the Title box with $Resources:String1.

  8. Replace the text in the Description box with $Resources:String2.

  9. Press F5 to build and run the solution.

  10. On the SharePoint page, click Site Settings on the Site Actions tab.

  11. Click the Site collection features link under Site Collection Administration.

  12. In the upper corner of the Site Collection Administration page, click the drop-down arrow next to your name and select the localized language. The feature title and description appear with localized resource strings.

  13. Switch the language back to the default and close the SharePoint page.

See Also

Tasks

How to: Localize a Feature

How to: Localize ASPX Markup

How to: Localize Code

How to: Add a Resource File