Localization with ASP.NET MVC ModelMetadata

Posted by kazimanzurrashid on ASP.net Weblogs See other posts from ASP.net Weblogs or by kazimanzurrashid
Published on Mon, 14 Jun 2010 02:12:02 GMT Indexed on 2010/06/14 2:12 UTC
Read the original article Hit count: 690

When using the DisplayFor/EditorFor there has been built-in support in ASP.NET MVC to show localized validation messages, but no support to show the associate label in localized text, unless you are using the .NET 4.0 with Mvc Future. Lets a say you are creating a create form for Product where you have support both English and German like the following.

English

create-en

German

create-de

I have recently added few helpers for localization in the MvcExtensions, lets see how we can use it to localize the form. As mentioned in the past that I am not a big fan when it comes to decorate class with attributes which is the recommended way in ASP.NET MVC. Instead, we will use the fluent configuration (Similar to FluentNHibernate or EF CodeFirst) of MvcExtensions to configure our View Models. For example for the above we will using:

public class ProductEditModelConfiguration : ModelMetadataConfiguration<ProductEditModel>
{
    public ProductEditModelConfiguration()
    {
        Configure(model => model.Id).Hide();

        Configure(model => model.Name).DisplayName(() => LocalizedTexts.Name)
                                      .Required(() => LocalizedTexts.NameCannotBeBlank)
                                      .MaximumLength(64, () => LocalizedTexts.NameCannotBeMoreThanSixtyFourCharacters);

        Configure(model => model.Category).DisplayName(() => LocalizedTexts.Category)
                                          .Required(() => LocalizedTexts.CategoryMustBeSelected)
                                          .AsDropDownList("categories", () => LocalizedTexts.SelectCategory);

        Configure(model => model.Supplier).DisplayName(() => LocalizedTexts.Supplier)
                                          .Required(() => LocalizedTexts.SupplierMustBeSelected)
                                          .AsListBox("suppliers");

        Configure(model => model.Price).DisplayName(() => LocalizedTexts.Price)
                                       .FormatAsCurrency()
                                       .Required(() => LocalizedTexts.PriceCannotBeBlank)
                                       .Range(10.00m, 1000.00m, () => LocalizedTexts.PriceMustBeBetweenTenToThousand);
    }
}

As you can we are using Func<string> to set the localized text, this is just an overload with the regular string method. There are few more methods in the ModelMetadata which accepts this Func<string> where localization can applied like Description, Watermark, ShortDisplayName etc. The LocalizedTexts is just a regular resource, we have both English and German:

mvc-localization-se

 

Now lets see the view markup:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Demo.Web.ProductEditModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    <%= LocalizedTexts.Create %>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= LocalizedTexts.Create %></h2>
    <%= Html.ValidationSummary(false, LocalizedTexts.CreateValidationSummary)%>
    <% Html.EnableClientValidation(); %>
    <% using (Html.BeginForm()) {%>
        <fieldset>
            <%= Html.EditorForModel() %>
            <p>
                <input type="submit" value="<%= LocalizedTexts.Create %>" />
            </p>
        </fieldset>
    <% } %>
    <div>
        <%= Html.ActionLink(LocalizedTexts.BackToList, "Index")%>
    </div>
</asp:Content>

As we can see that we are using the same LocalizedTexts for the other parts of the view which is not included in the ModelMetadata like the Page title, button text etc. We are also using EditorForModel instead of EditorFor for individual field and both are supported.

One of the added benefit of the fluent syntax based configuration is that we will get full compile type checking for our resource as we are not depending upon the string based resource name like the ASP.NET MVC.

You will find the complete localized CRUD example in the MvcExtensions sample folder.

That’s it for today.

Shout it

© ASP.net Weblogs or respective owner

Related posts about ASP.NET

Related posts about mvc