views:

371

answers:

2

Is it possible to put resource files (.resx) within subfolders inside App_GlobalResources?

For example:

/App_GlobalResources/someresources/myfile.resx

/App_GlobalResources/someresources/myfile.fr-fr.resx

/App_GlobalResources/othereresources/otherfile.resx

/App_GlobalResources/othereresources/otherfile.fr-fr.resx

Or, are all the .resx files placed directly inside App_GlobalResources?

If it is possible to use subfolders, how do you programmatically access resources within subfolders?

+1  A: 

It's possible. At least, I managed to do it.

Within a web site I added the App_GlobalResources folder. Inside it I created another folder "MyFolder" and placed MyResource.resx file inside. Resx file contained one pair MyKey1 - MyValue1.

Using the GetResource method of the following class I successfully extracted "MyValue1" for name="MyKey1"

static class Class1 {

    static Assembly FindGlobalResAssembly() {
        foreach(Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) {
            if(asm.FullName.StartsWith("App_GlobalResources."))
                return asm;
        }
        return null;
    }

    public static object GetResource(string name) {
        Assembly asm = FindGlobalResAssembly();
        if(asm == null)
            return null;
        return new ResourceManager("Resources.MyResource", asm).GetObject(name);
    }

}

This approach works in Medium trust also.

It seems that folders make no difference when accessing resources from code.

amartynov
+3  A: 

Technically, yes it is possible but there are some pitfalls. First, let me show you an example. Suppose my App_GlobalResources folder looks like so:

/App_GlobalResources
    /Test
        TestSubresource.resx
    TestResource.resx

Each resource file has a single entry called "TestString". I added each resource file using the Visual Studio menu so it created a class for me. By default, all classes added to the App_GlobalResources folder will have the same namespace of Resource. So, if I want to use the class generator and I want Test in the namespace, I need to go into the TestSubresource.Designer.cs file and manually change the namespace. Once I do that, I can do the following:

var rootResource = Resources.TestResource.TestString;
var subResource = Resources.Test.TestResource.TestString;

I can also reference them using GetGlobalResourceObject:

var rootResource = GetGlobalResourceObject( "TestResource", "TestString" );
var subResource1 = GetGlobalResourceObject( "TestSubresource", "TestString" );

Notice that I still use the "TestSubresource" as the means to reference the resources in that file even though it is in a subfolder. Now, one of the catches, is that all the files must be unique across all folders in App_GlobalResources or your project will throw a runtime error. If I add a resource named "TestResource.resx" to /Test, it will throw the following runtime error:

The resource file '/App_GlobalResources/TestResource.resx' cannot be used, as it conflicts with another file with the same name.). 

This is true even if I change the namespace on the new resource. So, in conclusion, yes it is possible, but you increase the odds of getting a runtime error because of two identically named resource files in different parts of the App_GlobalResources folder structure which is allowed by the file system but not by .NET.

Thomas