How to: Localize Site-Map Data

You can localize the following properties in a site map:

These properties are localized by using an explicit or implicit expression as the value of the property. For more information about expressions, see ASP.NET Expressions Overview. For information about resource files, see Resources in ASP.NET Applications.

To localize the Title or Description properties of a site-map node by using an explicit expression

  1. In your site map, set the EnableLocalization property to true. For example, in a Web.sitemap file, change the <siteMap> node to look like the following code:

    <siteMap enableLocalization="true">
    
  2. In your site map, change the value of the property that you want to localize to a resource string, such as the following case-sensitive line of code:

    $resources:ClassName,KeyName,DefaultValue
    

    For example, in a Web.sitemap file, your site-map node might look like the following example code.

    <siteMapNode 
      url="~/Home.aspx" 
      title="$resources:SiteMapLocalizations,HomePageTitle"
    description="$resources:SiteMapLocalizations,HomePageDescription,Default description"
      myCustomAttribute="$resources: CustomLocalizations,MyCustomAttribute"
    />
    

    The localized title and description are obtained from a file called SiteMapLocalizations.resx, by using the HomePageTitle and HomePageDescription resource keys. The localized custom attribute is obtained from a separate file called CustomLocalizations.resx. For more information about resource strings, see ASP.NET Expressions Overview.

  3. Create your .resx files in a folder called App_GlobalResources in the root of your application. Within the .resx file, individual property values are indexed by the value of the key name. For the preceding example, the SiteMapLocalizations.resx file might look like the following.

    <?xml version="1.0" encoding="utf-8"?>
    <root>
      <xsd:schema id="root"  xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xsd:element name="root" msdata:IsDataSet="true">
          <xsd:complexType>
            <xsd:choice maxOccurs="unbounded">
              <xsd:element name="metadata">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" />
                  <xsd:attribute name="type" type="xsd:string" />
                  <xsd:attribute name="mimetype" type="xsd:string" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="assembly">
                <xsd:complexType>
                  <xsd:attribute name="alias" type="xsd:string" />
                  <xsd:attribute name="name" type="xsd:string" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="data">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                    <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
                  <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
                  <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="resheader">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" use="required" />
                </xsd:complexType>
              </xsd:element>
            </xsd:choice>
          </xsd:complexType>
        </xsd:element>
      </xsd:schema>
      <resheader name="resmimetype">
        <value>text/microsoft-resx</value>
      </resheader>
      <resheader name="version">
        <value>2.0</value>
      </resheader>
      <resheader name="reader">
        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <resheader name="writer">
        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <data name="HomePageTitle">
        <value xml:space="preserve">Home Page</value>
      </data>
      <data name="HomePageDescription">
        <value xml:space="preserve">Home page of site</value>
      </data>
    </root>
    
  4. If you need to localize strings for multiple languages, you can create additional .resx files with locale information included in the file name. For example, the French version of your resource file would be named SiteMapLocalizations.fr.resx.

To localize the Title or Description properties of a site-map node by using an implicit expression

  1. In your site map, set the EnableLocalization property to true. For example, in a Web.sitemap file, change the <siteMap> node to look like the following code:

    <siteMap enableLocalization="true">
    
  2. In your site map, add an attribute called resourceKey to the site-map node that you want to localize by using the following case-sensitive line of code:

    resourceKey="HomePage"
    

    For example, in a Web.sitemap file, your <siteMap> node might look like the following code:

    <siteMapNode 
      url="~/Home.aspx" 
      resourceKey="HomePage"
      title = "Default Title"   
      description = "Default Description" 
     />
    

    The localized title and description are obtained from a file called Web.sitemap.resx using the HomePage.title and HomePage.description resource keys.

  3. Create your .resx file in a folder called App_GlobalResources in the root of your application. Within the .resx file, individual property values are indexed by the name. For the preceding example, the Web.sitemap.resx file might look like the following.

    Note

    Key names in global resource files should not include periods (.). However, periods are necessary in global resources that are referenced in site-map files when using implicit expressions. This is because of the resourceKey syntax. In some editing environments, such as Visual Web Developer, you might get a design-time error if you use a period in the key name. However, this shouldn't affect the ability to edit or save the file and can be ignored.

    <?xml version="1.0" encoding="utf-8"?>
    <root>
      <xsd:schema id="root"  xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xsd:element name="root" msdata:IsDataSet="true">
          <xsd:complexType>
            <xsd:choice maxOccurs="unbounded">
              <xsd:element name="metadata">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" />
                  <xsd:attribute name="type" type="xsd:string" />
                  <xsd:attribute name="mimetype" type="xsd:string" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="assembly">
                <xsd:complexType>
                  <xsd:attribute name="alias" type="xsd:string" />
                  <xsd:attribute name="name" type="xsd:string" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="data">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                    <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
                  <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
                  <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="resheader">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" use="required" />
                </xsd:complexType>
              </xsd:element>
            </xsd:choice>
          </xsd:complexType>
        </xsd:element>
      </xsd:schema>
      <resheader name="resmimetype">
        <value>text/microsoft-resx</value>
      </resheader>
      <resheader name="version">
        <value>2.0</value>
      </resheader>
      <resheader name="reader">
        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <resheader name="writer">
        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <data name="HomePage.description">
        <value xml:space="preserve">Home Page Description</value>
      </data>
      <data name="HomePage.Text">
        <value xml:space="preserve">Home Page Text from Resource File</value>
      </data>
      <data name="HomePage.title">
        <value xml:space="preserve">Home Page Title from Resource File</value>
      </data>
      <assembly alias="mscorlib" name="mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <data name="LabelResource1.Visible" type="System.Boolean, mscorlib">
        <value>True</value>
      </data>
    </root>
    
  4. If you need to localize strings for multiple languages, you can create additional .resx files with locale information included in the file name. For example, the French version of your resource file would be named Web.sitemap.fr.resx.

Localizing the URL Property in a Site Map

The Url property cannot be localized in a site map in the same way as the Title and Description properties.

To define different navigational structures based on a user's locale

  1. Define a different site-map file for each locale.

  2. Add each site map to the Web.config file. For more information, see How to: Configure Multiple Site Maps and Site-Map Providers.

  3. Programmatically switch to the appropriate Provider at run time. This is done by setting the SiteMapProvider property of the SiteMapDataSource object, or by setting the SiteMapProvider property of the SiteMapPath object, to the name of the provider. For more information, see How to: Programmatically Modify Site-Map Nodes in Memory.

Robust Programming

Explicit and implicit expressions can not be used in the same site-map file.

See Also

Tasks

How to: Configure Multiple Site Maps and Site-Map Providers

How to: Programmatically Modify Site-Map Nodes in Memory

Concepts

ASP.NET Site Maps

ASP.NET Expressions Overview

Securing ASP.NET Site Navigation

Securing Data Access

Reference

Title

Description

Attributes

Other Resources

Resources in ASP.NET Applications

ASP.NET Application Security in Hosted Environments