views:

733

answers:

3

Hi all,

Let's say we have such site structure:

App_LocalResources
      |- A.aspx.resx
      |- B.aspx.resx
A.aspx
B.aspx

Now I use HttpContext.GetLocalResourceObject("~/A.aspx", "Key1") in A.aspx.cs, and it works fine. But if I use HttpContext.GetLocalResourceObject("~/A.aspx", "Key1") in B.aspx.cs, it throws an exception:

The resource class for this page was not found. Please check if the resource file exists and try again.

Exception Details: System.InvalidOperationException: The resource class for this page was not found. Please check if the resource file exists and try again.

How can I resolve this problem? I want to read the local resources from an external page, and I don't want to read the .resx file myself. Thanks :-)

UPDATE: In my case, there're some "data.xml" files(they are in different directories, and have elements like <key name='Key1' value='value1' />), and the contents of them will be rendered as html.

But the key names in the data.xml should be localized before rendering (different data.xml contain different keys).

For example, the data.xml has such an element:

<key name='CategoryId' value='3' />

In the result html page, I want to display "Category Id = 3" for en-US culture, and "类别=3" for zh-CN culture, etc.

So I think I can create some files following the pattern "data.xml.??-??.resx" in the App_LocalResources folder, then use the HttpContext.GetLocalResource() for each data.xml to retrieve the localized key names. That way I don't need to read the xml myself. Is it possible?

+2  A: 

That's not the way that local resources are supposed to be used. Local resources are only valid for a page or control. You should use global resources in your case.

From MSDN

Global Resource Files

You create a global resource file by putting it in the reserved folder App_GlobalResources at the root of the application. Any .resx file that is in the App_GlobalResources folder has global scope. Additionally, ASP.NET generates a strongly typed object that gives you a simple way to programmatically access global resources.

Local Resource Files

A local resources file is one that applies to only one ASP.NET page or user control (an ASP.NET file that has a file-name extension of .aspx, .ascx, or .master). You put local resource files in folders that have the reserved name App_LocalResources. Unlike the root App_GlobalResources folder, App_LocalResources folders can be in any folder in the application. You associate a set of resources files with a specific Web page by using the name of the resource file.

And could be also useful for you to check how access resources programatically

    Button1.Text = 
        GetLocalResourceObject("Button1.Text").ToString();
    Image1.ImageUrl = 
        (String)GetGlobalResourceObject(
        "WebResourcesGlobal", "LogoUrl");
    Image1.Visible = true;
Claudio Redi
Thanks. But I do need the App_LocalResources, not the App_GlobalResources. I need to read the local resources for each page / user control in my class library.
Dylan Lin
well, then you have to use local resources for page A on page A and local resources for page B on page B :-) Crossed references are not allowed
Claudio Redi
But, if we can only access the A.aspx.resx on A.aspx, why there exists the HttpContext.GetLocalResource() method? We already can access the A.aspx.resx on A.aspx by using this.GetLocalResourceObject() method.
Dylan Lin
I'd say not for access cross page resources. Resources used on more than one page should be global. If you can do something doesn't mean that you should do it :-) The correct approach for shared resources is global storage.
Claudio Redi
Hi, in my case, there're some data.xml files(they are in different directories, and have elements like "<key name='Key1' value='value1' />"), and the contents of them will be rendered as html. But the key names in the data.xml should be localized before rendering (different data.xml contain different keys). So I think may be I can create some files following the pattern "data.xml.??-??.resx" in the App_LocalResources folder, then use the HttpContext.GetLocalResource() for each data.xml to retrieve the localized key names. That way I don't need to read the xml myself.
Dylan Lin
I agree with the recommendation to use Global Resources rather than local ones.
Greg
+1  A: 

As Claudio Redi recommended, use Global Resource files.

I would create one per xml file in the format of "filename.resx", so in your example, you'd name it Data.resx.

Set the "Name" in the resource to your "name" attribute and the Value equal to the translated "name".

For example, in Data.resx, you'd have Name=CategoryId, Value=Category Id. In Data.zh-CN.resx, you'd have Name=CategoryId, Value=类别.

One you have the data in the resource files, you'd probably want to create a class wraps the functionality of the XML lookup and localization for your in your application. Something like this should work:

public class Data
{
    private const string fileLocation = "TODO";

    public string Name{ get; set; }
    public string Value{ get; set; }

    private Data()
    {

    }

    public Data( string Name )
    {
        // TODO: Look up the single key from XML
    }

    public string GetLocalizedName( CultureInfo cultureInfo )
    {
        return Resources.Data.ResourceManager.GetString(Name, cultureInfo);
    }

    public static List<Data> LoadData()
    {
        List<Data> dataList = new List<Data>();

       // TODO: Load XML and create a list of Data objects.

        return dataList;
    }
}
Greg
Thanks! But I have many data.xml. Actually, the system supports plugins, and every plugin has it's own data.xml. My system (plugin host) should take the responsibility for localizing the key names in the data.xml files. So I think the data.xml should be placed in the plugin folder, and the .resx files should also be placed in the plugin folder.
Dylan Lin
What if someone provides a string through the plug-in that you don't have a translation for? Or do they need to be provided with the plug-in as well?At this point, you're well outside the Use Cases for .NET localization and you probably need to come up with an idea that works well for your system instead of forcing it to fit within .NET localization.
Greg
A: 

How can I resolve this problem? I want to read the local resources from an external page, and I don't want to read the .resx file myself

If you really want to do that you must provide a key e.g.

HttpContext.GetLocalResourceObject("/A.aspx","CategoryData")

This assumes that the A.aspx.zh-CN.resx contians.

<data name="CategoryData" xml:space="preserve">
    <value>"类别=3"</value>
  </data>
Conrad Frix
Thanks. But in real code, I have provided the key. That's only a typing mistake of the post.
Dylan Lin
I would run ildasm and check to see that your resource exists. WebApplicationName-> WebApplicationName.App_LocalResources--> WebApplicationName.App_LocalResources.A_aspx---> Key1If it doesn't there's probably an issue with the way you created your resource file
Conrad Frix