Walkthrough: Creating Localized Resources in ASP.NET

MVC Resources .NET Framework
Localized Resources in .NET give you the opportunity to provide translated or locale-specific content for your users. The ideal uses are for page titles and small pieces of text, menu items, etc., along with region-specific images.

This technique is not designed to replace complex database content, but it does enable you to make your website more friendly to your international users, without the need for writing custom translation code.

I earlier wrote a post about how to use Resources (*.resx files) in .NET, and I highly recommend that you read that post before reading this one, as I try not to include duplicate content in my posts.

I will provide examples in code, but you should try this for yourself by following along in Visual Studio. So let's get VS opened up and create a new ASP.NET MVC Web Application (.NET Framework). Make sure you select MVC as the project template.

We'll use classic .NET Framework because it's easier, but I'll probably do a post about doing this in .NET Core at a later date.

Step 1 - Create the resx files



Let's create our desired folder in the project root: App_GlobalResources

Now, right click on this folder and select Add > Resources File

Type a name: MyResource.resx

Then, add a second resource file called: MyResource.nb.resx

Note: nb here indicates we want to use language "Norwegian Bokmaal", the main language spoken in Norway.

We should now see both files in the App_GlobalResoures folder.

Step 2 - Set the *.resx file properties



IMPORTANT! Before you start playing around with your resx files, it is important to set the correct file properties. Failing to do this may result in Visual Studio crashing.

  1. Give a single left-click to the MyResource.resx file.

  2. Locate the "File Properties" window

  3. Set the Build Action to Embedded resource

  4. Set the Custom Tool to ResXFileCodeGenerator

  5. Set the Custom Tool Namespace to MyWebApplication.Resources


  1. Give a single left-click to the MyResource.nb.resx file.

  2. Locate the "File Properties" window

  3. Set the Build Action to Embedded resource

  4. Set the Custom Tool to GlobalResourceProxyGenerator

  5. Set the Custom Tool Namespace to MyWebApplication.Resources


Note: MyWebApplication should reflect the namespace of your project

Step 3 - Add some content



Open up our default resource file MyResource.resx and add some content as follows:

Name      | Value
------------------------------
Title | A Tasty Breakfast
Breakfast | Pancakes and honey


Feeling hungry yet? Good.

Whilst you're in this file, notice the "Access Modifier" drop-down menu. Set it to "Public".

Now to open up MyResource.nb.resx and we will add our translated content:

Name      | Value
---------------------------------
Title | En Deilig Frokost
Breakfast | Pannekaker og honning


Step 4 - Consume the static string properties



Get it? Hungry, breakfast, "consume" ...? Oh well.

As you created a new MVC project, you should get a few default *.cshtml files.
Open the file: Views\Home\Index.cshtml

Notice that ViewBag.Title = "Home Page"; has a default string value.

Change this line to the following code:
ViewBag.Title = MyWebApplication.Resources.MyResource.Title;


Whilst we're in this file, let's add a new div element with the following code:
< div > @MyWebApplication.Resources.MyResource.Breakfast < / div >


Step 5 - A quick test!



Build and run your code. When it loads in the browser, the page title should be "A Tasty Breakfast" and you should see "Pancakes and honey" somewhere on the home page.

Step 6 - Set the thread culture



Now comes the fun part. We need to read the browser language and set the UI culture of the current thread.

Open up the Controllers\HomeController.cs file and add the following code:

namespace MyWebApplication.Controllers
{
public class HomeController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);

if (filterContext.HttpContext != null &&
filterContext.HttpContext.Request != null &&
filterContext.HttpContext.Request.UserLanguages != null &&
filterContext.HttpContext.Request.UserLanguages.Length > 0)
{
var lang = filterContext.HttpContext.Request.UserLanguages[0];

if (!String.IsNullOrWhiteSpace(lang))
{
try
{
var culture = new CultureInfo(lang);

System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
}
catch { }
}
}
}

// controller action methods
}
}


This code checks for a valid user language from the incoming http request and sets the user interface culture for the current thread, before the Action runs.

Note: This could also be achieved by creating a custom ActionFilter attribute and adding it to the GlobalFilters.Filters collection.

Step 7 - Set our browser language and test it



Ok, the hard part's over. Now, open up your favourite browser (I like Firefox 🦊) and set your preferred page language to Norwegian Bokmaal.

In Firefox, you find this under Options > General > Language and Appearance > Lanuage > Choose your preferred language for displaying pages > [Choose...]

Now go back to Visual Studio, and get ready to Debug your project.

In the dropdown menu next to "▶ IIS Express" make sure to select the correct target Web Browser.

Now, run the project and check the result in the web browser. If the page title is "En Deilig Frokost" and you see "Pannekaker og honning" on the home page, CONGRATULATIONS, you did everything correctly!

What's really happening behind the scenes?



Your browser is sending a http request header like this:
Accept-Language: nb

See: developer.mozilla.org

This "Accept-Language" header is being read by the .NET Framework and being passed in the UserLanguages array of the Request object. That is what is enabling you to set the current thread UI culture.

When the CurrentUICulture property is set, the .NET Framework is automatically routing the access of each public static string property in the resource to the appropriate, localised resx file. Pretty cool!

Happy coding! Please remember to support me! 🤓
Hey you! I need your help!

Thanks for reading! All the content on this site is free, but I need your help to spread the word. Please support me by:

  1. Sharing my page on Facebook
  2. Tweeting my page on Twitter
  3. Posting my page on LinkedIn
  4. Bookmarking this site and returning in the near future
Thank you!