37

What are the best usage of the following resource files.

  1. Properties → Resources (Phil used this resource for localization in DataAnnotation)
  2. App_GlobalResources folder
  3. App_LocalResources folder

I also would like to know what is the difference between (1) and (2) in asp.net mvc application.

3 Answers 3

32

You should avoid App_GlobalResources and App_LocalResources. Like Craig mentioned, there are problems with App_GlobalResources/App_LocalResources because you can't access them outside of the ASP.NET runtime. A good example of how this would be problematic is when you're unit testing your app.

K. Scott Allen blogged about this a while ago. He does a good job of explaining the problem with App_GlobalResources in ASP.NET MVC here.

Sign up to request clarification or add additional context in comments.

Comments

12

If you go with the recommended solution (1) (i.e. as in K. Scott Allen's blog):

For those of you trying to use explicit localization expressions (aka declarative resource binding expressions), e.g. <%$ Resources, MyResource:SomeString %>

public class AppResourceProvider : IResourceProvider
{
    private readonly string _ResourceClassName;
    ResourceManager _ResourceManager = null;

    public AppResourceProvider(string className)
    {
        _ResourceClassName = className;
    }

    public object GetObject(string resourceKey, System.Globalization.CultureInfo culture)
    {
        EnsureResourceManager();
        if (culture == null)
        {
            culture = CultureInfo.CurrentUICulture;
        }
        return _ResourceManager.GetObject(resourceKey, culture);
    }

    public System.Resources.IResourceReader ResourceReader
    {
        get
        {
            // Not needed for global resources
            throw new NotSupportedException();
        }
    }

    private void EnsureResourceManager()
    {
        var assembly = typeof(Resources.ResourceInAppToGetAssembly).Assembly;
        String resourceFullName = String.Format("{0}.Resources.{1}", assembly.GetName().Name, _ResourceClassName);
        _ResourceManager = new global::System.Resources.ResourceManager(resourceFullName, assembly);
        _ResourceManager.IgnoreCase = true;
    }
}

public class AppResourceProviderFactory : ResourceProviderFactory
{
    // Thank you, .NET, for providing no way to override global resource providing w/o also overriding local resource providing
    private static Type ResXProviderType = typeof(ResourceProviderFactory).Assembly.GetType("System.Web.Compilation.ResXResourceProviderFactory");
    ResourceProviderFactory _DefaultFactory;

    public AppResourceProviderFactory()
    {
        _DefaultFactory = (ResourceProviderFactory)Activator.CreateInstance(ResXProviderType);
    }

    public override IResourceProvider CreateGlobalResourceProvider(string classKey)
    {
        return new AppResourceProvider(classKey);
    }

    public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
    {
        return _DefaultFactory.CreateLocalResourceProvider(virtualPath);
    }
}

Then, add this to your web.config:

    <globalization requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="utf-8" culture="en-US" uiCulture="en"
                   resourceProviderFactoryType="Vendalism.ResourceProvider.AppResourceProviderFactory" />

1 Comment

What is Resources.ResourceInAppToGetAssembly? It doesn't compile and I can't find any reference to it but in this example? Is it a pseudonym for the actual resources class you're using?
7

Properties → Resources can be seen outside of your views and strong types are generated when you compile your application.

App_* is compiled by ASP.NET, when your views are compiled. They're only available in the view. See this page for global vs. local.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.