DevelopMENTAL Madness

Wednesday, May 20, 2009

ASP.NET MVC Globalization/Localization: Referencing Resource Files in Your View

I’ve been using ASP.NET MVC since Preview 1 (Nov 2007). When I need to reference a Resource File (.resx) in my View, I just do the following:

   1: <%=Resources.MyResourceFile.MyResourceKey%>

Until today, I took that for granted. I received an email this morning referencing this post on ASP.NET. The post was about using Resource Files in an MVC View. I replied to the original post in February 2008 and then forgot about it. Today, I was asked how I got this to work. Since I hadn’t ever given it much thought – it just worked – I dove in a bit to answer the post and here’s what I got.

Create Your Resource (.resx) File

There are 3 ways to create a Resources file in an ASP.NET application (MVC or WebForms):

  1. Add New Item: Right-click anyware –> Add –> New Item…
  2. Add to App_GlobalResources:
    1. Right-click your project –> Add –> Add ASP.NET Folder –> App_GlobalResources
    2. Right-click App_GlobalResources –> Add –> New Item…
  3. Add to App_LocalResources:
    1. Right-click a folder –> Add –> Add ASP.NET Folder –> App_LocalResources

Local Resource Files

1 and 3 are essentially the same, I’ll refer to the result as a local resource file.When you create a local resource file all you need to do after you’ve added a view string values to the file is change the “Access Modifier” setting to “Public”.

VSResourceFile

The only difference (as far as I can tell) between 1 and 3 is that the default value for Access Modifier for 1 is “Internal” and for 3 it’s “No code generation”. There may be some differences with regard to WebForms, but honestly I never noticed before.

Global Resource Files

Number 2 is just as easy, but there is a little more to explain, and here’s why: you can’t change the Access Modifier for a Global Resource File. If you create a Global Resource File and open it you’ll notice the option is disabled.

VSGlobalResourceFile

The only option for a Global Resource File is “Internal”. It reads public on the toolbar. But if you look at the designer.cs file you will see that the class and all its properties are marked as “internal”.

However, you can still easily use a Global Resource File, with just one caveat. Intellisense doesn’t quite work the way you would expect (or maybe you would). The namespace will show up on intellisense, the class name will not, but once you have correctly typed the namespace and class name you’ll get intellisense for all your keys.

Here you see the namespace in intellisense:

VSIntellisenseNamespace

Here you see nothing comes up for the class:

VSIntellisenseClass

But here you see the keys are picked up by intellisense once you enter the class name correctly:

VSIntellisenseProperties

The funny thing is that this is not always true. Sometimes you will get intellisense for the class name and sometimes you won’t. Either way you can either use Local Resource Files or as suggested by Steven Sanderson in his book Pro ASP.NET MVC Framework (Apress) you can create a separate Class Library Project for resources and just make the visibility public.

I’ve seen extension functions written for access to resources and frankly this seems the simplest way. Not to mention you get compile checking and intellisense support. I really don’t like having to type in string keys, I make too many typing mistakes to trust myself in that way.

Labels: ,