ASP.NET MVC - Using Resource Files to Manage String Constants

This article is from our ASP.NET MVC 101 Tutorial Series

Continuing with the MVC 101 series, today we explore how to save strings in Resource files instead of constants spread out all over the application or worse, hard coded in the source itself.
Mind you, we are not looking at cultures and Internationalization today.

It is very easy to start working on a project and continue adding string in a random, unstructured and adhoc mixture of inline strings and string constants. However, as soon as the marketing team starts to demo the product, you get one change request after the other to update the text/message and error notifications. This is when things go south and you wish you had a central place to store all your string constants.

Hello Resource Files!


Getting Started

Let’s assume we have an ASP.NET MVC Web Application that uses Entity Framework and SQL Server for data management.

For brevity I’ll lump all of them together.

We start off with an ASP.NET MVC 4 Internet Application template that does the ‘important’ task of storing Addresses to a database. It’s easy to get started with EF Code first so we define a POCO as follows:


public class Address
{
[Key]
public int Id { get; set; }
public string Street { get; set; }
public string Locality { get; set; }
public string Country { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}

Next we create a Controller and let the MVC Tooling generate a AddressController and the required DBContext class for it.

Now when we run the application and navigate to /Address, we get the following Index Page.

default-address-index

Now as we can see, there are a lot of defaults like the text ‘your logo here’ or ‘My ASP.NET MVC Application’. Also the Names of the columns are same as the property name. Now let’s say we wanted to modify these, we could easily use the Display attribute on each property and describe custom labels for them. However, we don’t want to do inline text or ‘magic strings’. So let’s see what it takes to do things via resource files.

Bringing in Resource Files

Resource files as we all know are xml files with .resx extension and have a dedicated designer to manipulate them in Visual Studio.

Now in the olden days, one would drop resource files in the App_LocalResources folder. However that prevents you from sharing Resources in the Domain layer for example. To avoid this scenario, we add a new Class Library project to our MVC solution and add a new Resource file to it.

newly-added-resource-file

Changing the Access Modifier

The thing to note and update here is the Access Modifier dropdown. By default, it is set to Internal. This makes the scope of the Resource file limited to the particular dll only. But in our case, we have a separate dll dedicated to the Resources and we’ll be referring this dll in our other projects. So to enable access to the resources we change the Access Modifier to ‘Public’.

Adding Resource Strings

After updating the Access modifier, let’s add a few resource strings. Mind you the Name has to be unique per resource file. Internally Visual Studio generates a static class for you, for easy reference

resource-file-with-strings

As we can see, we have defined three resource strings, one for the Application Name itself, next a Display String for the Street column in our POCO and one for an Error Message in case the Street property was left blank.

Using the Resource Strings

Now let’s use the Resource Strings that we defined above. To do this first we need to add reference of the Resource project into our web project. Once added, we can go ahead and use the resource strings.
Using the Static Variables
- In _Layout.cshtml, first thing we’ve to do is add a using statement at the top of the page

@using ResourceFilesSample.Resources

- Next we replace the magic string “your logo here” with ApplicationName as follows

<p class="site-title">@Html.ActionLink(ViewResources.ApplicationName, "Index", "Home")</p>

- Similarly we update the Title and the Footer to show ApplicationName instead of the default hardcoded Text

As we can see in these examples, ViewResources (the name of the resx file) is treated as a Static class with the Resource Names mapping to static fields.
Using Resources in Model Attributes
Now that we have seen how to use Resource string in the view, let’s see how we can leverage them in Defining Data Attributes.

We update the Address POCO as follows by adding a Required constraint, a Display message and an Error message in case the Required constraint is missing

public class Address
{
    [Key]
    public int Id { get; set; }
    [Display(Name="StreetDisplay",
        ResourceType=typeof(ViewResources))]
    [Required(AllowEmptyStrings=false,
        ErrorMessageResourceName="StreetErrorMandatory",
        ErrorMessageResourceType=typeof(ViewResources))]
    public string Street { get; set; }
    public string Locality { get; set; }
    public string Country { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

As we can see, we have added a Display attribute and passed it two parameters, first is a string corresponding to the Resource name and next the Type of the Resource object which in our case is ResourceFilesSample.Resources.ViewResources.

Second attribute added is the Required field. It has two parameters defining the resource again, first one has the name of the resource as a String and second is the Type of the Resource object.
With these changes in place, we have to do one last thing before we can run the application. Since we are using EF Code First, we have to enable migrations and run the migrations so that the database is updated with the ‘Required’ field change for the Street column. In Package management console, execute the following commands

PM> Enable-Migrations -ContextTypeName ResourceFilesSample.Web.Models.ResourceFilesSample.WebContext –EnableAutomaticMigrations

Followed by

PM> update-database

Once database update is complete, run the Application and navigate to the /Address controller’s Index page. The Index page looks as follows

updated-address-index

As we can see, instead of the column name Street we get to see ‘Name of Street’ from the resource file

error-message-from-resource

Now let’s click on Create New and try to save an Address without the name of the street. As we can see, we get the error message as we had described in our Resource file.

Conclusion

With that we conclude this primer on how to get started with string constants in Resource files. Using Resource files have the added advantage of being much easier to Internationalize by simply adding new Resource files with different culture suffixes.

The entire source code of this article can be downloaded at https://github.com/devcurry/mvc101-using-resource-strings  




2 comments:

Unknown said...

If you need a .resx translation management tool that is also integrated with GitHub, you should have a look at the software localization platform POEditor.
Collaborative localization and crowdsourced translation can be greatly automated with an online solution like this one.

Madman said...

Thanks, very helpful!