CodeDigest.Com Logo
Featured:

Using Resource File for DataAnnotations Display Attribute with Multi Language Support in Asp.Net MVC

Tagged as: Asp.Net MVC Posted By

We use the attributes defined in System.ComponentModel.DataAnnotations namespace to supply meta data for model classes. This Meta data defined using these attributes will be used by Entity Framework for model generation and Asp.Net MVC framework for validations and scaffolding UI components, etc. One such attribute is DisplayAttribute which is used to define the display title for the field. The value defined in this attribute will be used by the html helper (@Html.DisplayNameFor(model => model.FirstName)) to display the title for the field.

At times, it would be helpful if we can provide resource files to define the display title instead of hard coding inside the [Display] attribute. By using resource file, it will be easier to change the display name instead changing the C# class file. It also helps in localization of display attributes. This simple article will help us to manage the display titles using resource files with multi language support in an Asp.Net MVC application. The Display attribute already includes supports reading from resource file through a parameter called ResourceType.

 

 

For demonstration, we will use a simple Employee-Department model with Entity Framework Code First and Asp.Net MVC 5.0 solution using Visual Studio 2015. The project requires all the Nuget packages required for Asp.Net MVC 5.0 and the latest Entity Framework package included in the solution.

Creating Resource File and Configuring Model Class

To add a resource file into your solution, right click project in solution explorer and click Add > New Item.. In the Add New Item dialogue, select “Resources File” under General category. Rename the file name to EmployeeResx.resx and Click Add. I have added the file under Models/RESX folder in my solution.

Now, let’s add display attribute to the properties of Employee object and configure it to look for the display title in EmployeeResx.resx file. Code below.

 

public class Employee
{
    //Table properties
    [Key]
    public int EmployeeId { get; set; }
    public int DepartmentId { get; set; }

    [MaxLength(50)]
    [Display(Name = "FirstName", ResourceType = typeof(EmployeeResx))]
    public string FirstName { get; set; }

    [Display(Name = "LastName", ResourceType = typeof(EmployeeResx))]
    [MaxLength(50)]
    public string LastName { get; set; }

    [Display(Name = "Address1", ResourceType = typeof(EmployeeResx))]
    [MaxLength(50)]
    public string Address1 { get; set; }

    [Display(Name = "Address2", ResourceType = typeof(EmployeeResx))]
    [MaxLength(50)]
    public string Address2 { get; set; }

    [Display(Name = "City", ResourceType = typeof(EmployeeResx))]
    [MaxLength(50)]
    public string City { get; set; }

    [Display(Name = "State", ResourceType = typeof(EmployeeResx))]
    [MaxLength(50)]
    public string State { get; set; }

    [Display(Name = "Country", ResourceType = typeof(EmployeeResx))]
    [MaxLength(50)]
    public string Country { get; set; }

    [Display(Name = "PostalCode", ResourceType = typeof(EmployeeResx))]
    [MaxLength(10)]
    public string PostalCode { get; set; }

    [Display(Name = "Email", ResourceType = typeof(EmployeeResx))]
    [MaxLength(100)]
    public string Email { get; set; }

    [Display(Name = "DOB", ResourceType = typeof(EmployeeResx))]
    public DateTime? DOB { get; set; }

    [Display(Name = "Gender", ResourceType = typeof(EmployeeResx))]
    [MaxLength(10)]
    public string Gender { get; set; }

    [Display(Name = "IsPermanent", ResourceType = typeof(EmployeeResx))]
    public bool IsPermanent { get; set; }

    [Display(Name = "Salary", ResourceType = typeof(EmployeeResx))]
    public decimal Salary { get; set; }

    public virtual Department Department { get; set; }
}
 

Next, we need to add the key-value pair for all the Employee properties in the added resource file like below. The Name should match the value defined for Name parameter in Display attribute.

When executed, you can see the display title coming from the resource file like below.

Note: You may get an error “Cannot retrieve property 'Name' because localization failed.  Type 'Xxxx.EmployeeResx' is not public or does not contain a public static string property with the name 'FirstName'.“. This is because, by default the resource file properties have access modifier set to internal. Change it to Public in the Access Modifier dropdown in the resource file toolbar. Refer below image.

 

Now, let’s add another resource file for adding support for another language, for example, Tamil. Add a new resource file and name it as EmployeeResx.ta.resx. The file name must include language code ta for Tamil as part of the name (EmployeeResx.ta.resx). Doing this will make the resource file to get picked automatically when the current UI thread culture is set to culture code ta-IN. Refer here to know the list of language-country code. The Tamil resource file will look like below.

When executed, you can see the title changed to Tamil when the current UI thread culture is set to Tamil.

Note:

I have set the current UI thread’s culture from Global.asax file by accepting the Request object’s language header set by the client browser.

 

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    if (Request.UserLanguages != null)
    {
        string culture = Request.UserLanguages[0];

        Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(culture);
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
    }
}

 

To make the browser add the language header, in Firefox, go to Tools>Options>Content. Click Choose.. button under Languages. Add the preferred language (Tamil in this article) from the dropdown and use the Move Up button to make it as first preference.

Download the source and see it in action.

 



Feedback

Comments

Attached source code is incorrect
The attached source code is in not what is discussed above. It is grid demo.
Commented by DotNetUser on 5/15/2018 7:20:50 PM

Excellent and to the point solution
Excellent solution, no need to add new custom classes extended from Attribue. Thumbs up....
Commented by Asad Naeem on 3/12/2018 12:22:57 AM