Shaun Xu

The Sheep-Pen of the Shaun


News

logo

Shaun, the author of this blog is a semi-geek, clumsy developer, passionate speaker and incapable architect with about 10 years experience in .NET. He hopes to prove that software development is art rather than manufacturing. He's into cloud computing platform and technologies (Windows Azure, Aliyun) as well as WCF and ASP.NET MVC. Recently he's falling in love with JavaScript and Node.js.

Currently Shaun is working at IGT Technology Development (Beijing) Co., Ltd. as the architect responsible for product framework design and development.

MVP

My Stats

  • Posts - 94
  • Comments - 335
  • Trackbacks - 0

Tag Cloud


Recent Comments


Recent Posts


Archives


Post Categories



An upgraded article and solution had been posted here. I migrated the project to ASP.NET MVC 4 with some features added.

- Upgraded to ASP.NET MVC 4, Visual Studio 2012.
- Moved the solution to a separated project.
- Moved the procedure originally executed in base controller's ExecuteCore to a separated class. Now can use the this solution without needing inherit from the localization base controller.
- Implemented the localization resource provders so that can use any data source (database, XML file, etc.) to store the localization resource.
- Improved the language selector bar. Now can use partial view as the selected and unselected link content with images, scripts, etc.

Localization is a common issue when we develop a world wide web application. The key point of making your application localizable is to separate the page content from your logic implementation. That means, when you want to display something on the page, never put them directly on the page file (or the backend logic). You should give the content a key which can be linked to the real content for the proper language setting.

Last week I was implementing the localization on my ASP.NET MVC application. This is my first time to do it so I spent about 3 days for investigation, trying and come up with a final solution which only needs 1 day’s job. So let’s take a look on what I have done.

 

Localization supported by ASP.NET MVC

ASP.NET MVC was built on top of the ASP.NET runtime so all feature provided by ASP.NET can be used in MVC without any wheaks such as caching, session state and localization. In the traditional ASP.NET web form ages we were using the resource files to store the content of the application with different cultures and using the ResourceManager class to retrieve them which can be generated by Visual Studio automatically. In ASP.NET MVC they works well.

Let’s create a standard ASP.NET MVC application for an example. The website was in English and we can see all content are hard-written in the view pages and the controller classes.

image

Now what I need to do is to put all contents out of from the pages and the controllers. ASP.NET gives us a special folder named App_GlobalResources which contains the resource files for the content of all cultures. Just right-click the project in the solution explorer window and create the folder under the Add > Add ASP.NET Folders menu.

I created 2 resource files for 2 langauges: English and Chinese. The English would be the default language of this application so I will create Global.resx file firstly, then Global.zh.resx. The middle name ‘zh’ was the culture name of this language. If we need a French version in the future we can simply create Global.fr.resx. The Visual Studio will help us to generate the accessing class for them.

image

Then let’s move some content into the resource files. In the home page there are 3 places need to be changed: the title, message and the description. So we add 3 items in our 2 resource files.

image

The title and the description are defined in the view page so we will change the view page. It will load the content through the access class generated by Visual Studio.

   1: <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
   2:  
   3: <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   4:     <%
   1: : Resources.Global.HomeIndex_Title 
%>
   5: </asp:Content>
   6:  
   7: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
   8:     <h2><%
   1: : ViewData["Message"] 
%></h2>
   9:     <p>
  10:         <%
   1: : Resources.Global.Home_Index_Desc 
%> <a href="http://asp.net/mvc" title='<%: Resources.Global.Home_Index_DescLink %>'>http://asp.net/mvc</a>
  11:     </p>
  12: </asp:Content>

The message was defined in the controller class and passed to the view page through the ViewData so we also need to change the home controller as well.

   1: public ActionResult Index()
   2: {
   3:     ViewData["Message"] = Resources.Global.HomeIndex_Message;
   4:  
   5:     return View();
   6: }

 

Specify the language through the URL

We had moved the content into the resource files but our application does not support localization since there’s no place we can specify the language setting. In order to make it as simple as possible we will make the URL indicate the current selected language, which means if my URL was http://localhost/en-US/Home/Index it will in English while http://localhost/zh-CN/Home/Index will in Chinese. The user can change the language at any pages he’s staying, and also when he want to share the URL it will pass his language setting as well.

In order to do so I changed the application routes, add a new route with a new partten named lang in front of the controller.

   1: public static void RegisterRoutes(RouteCollection routes)
   2: {
   3:     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   4:  
   5:     routes.MapRoute(
   6:         "Localization", // Route name
   7:         "{lang}/{controller}/{action}/{id}", // URL with parameters
   8:         new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
   9:     );
  10:  
  11:     routes.MapRoute(
  12:         "Default", // Route name
  13:         "{controller}/{action}/{id}", // URL with parameters
  14:         new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
  15:     );
  16:  
  17: }

You may noticed that I added a new route rather than modifed the default route, and didn’t specify the default value of the {lang} pattern. It’s because we need the default route render the default request which without the language setting such as http://localhost/ and http://localhost/Home/Index.

If I modied the default route, http://localhost/ cannot be routed; and the http://localhost/Home/Index would be routed to lang = Home, controller = Index which is incorrect.

Since we need the URL control the language setting we should perform some logic before each action was executed. The ActionFilter would be a good solution in this scenario.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.Web.Mvc;
   6: using System.Threading;
   7: using System.Globalization;
   8:  
   9: namespace ShaunXu.MvcLocalization
  10: {
  11:     public class LocalizationAttribute : ActionFilterAttribute
  12:     {
  13:         public override void OnActionExecuting(ActionExecutingContext filterContext)
  14:         {
  15:             if (filterContext.RouteData.Values["lang"] != null &&
  16:                 !string.IsNullOrWhiteSpace(filterContext.RouteData.Values["lang"].ToString()))
  17:             {
  18:                 // set the culture from the route data (url)
  19:                 var lang = filterContext.RouteData.Values["lang"].ToString();
  20:                 Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang);
  21:             }
  22:             else
  23:             {
  24:                 // load the culture info from the cookie
  25:                 var cookie = filterContext.HttpContext.Request.Cookies["ShaunXu.MvcLocalization.CurrentUICulture"];
  26:                 var langHeader = string.Empty;
  27:                 if (cookie != null)
  28:                 {
  29:                     // set the culture by the cookie content
  30:                     langHeader = cookie.Value;
  31:                     Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);
  32:                 }
  33:                 else
  34:                 {
  35:                     // set the culture by the location if not speicified
  36:                     langHeader = filterContext.HttpContext.Request.UserLanguages[0];
  37:                     Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);
  38:                 }
  39:                 // set the lang value into route data
  40:                 filterContext.RouteData.Values["lang"] = langHeader;
  41:             }
  42:  
  43:             // save the location into cookie
  44:             HttpCookie _cookie = new HttpCookie("ShaunXu.MvcLocalization.CurrentUICulture", Thread.CurrentThread.CurrentUICulture.Name);
  45:             _cookie.Expires = DateTime.Now.AddYears(1);
  46:             filterContext.HttpContext.Response.SetCookie(_cookie);
  47:  
  48:             base.OnActionExecuting(filterContext);
  49:         }
  50:     }
  51: }

I created an attribute named LocalizationAttribute which inherited from the ActionFilterAttribute and overrided its OnActionExecuting method. I firstly checked the RouteData. If it contains the language setting I will set it to the CurrentUICulture of the CurrentThread, which will indicate the resource manager (generated by Visual Studio based on the resource files) retrieve the related value.

If no language setting in the RouteData I checked the cookie and set it if available. Otherwise I used the user language of the HttpRequest and set into the current thread.

Finally I set the language setting back to the route data so all coming actions would retrieve it and also saved it into the cookie so that next time the user opened the browser he will see his last language setting.

Then I applied the attribute on the home controller so that all actions will perform my localization logic.

   1: namespace ShaunXu.MvcLocalization.Controllers
   2: {
   3:     [HandleError]
   4:     [Localization]
   5:     public class HomeController : Controller
   6:     {
   7:         public ActionResult Index()
   8:         {
   9:             ViewData["Message"] = Resources.Global.HomeIndex_Message;
  10:  
  11:             return View();
  12:         }
  13:  
  14:         public ActionResult About()
  15:         {
  16:             return View();
  17:         }
  18:     }
  19: }

Now if we start the application and add the language setting on the URL we can see the result.

image

image

 

Links for the language selection

Let the user change the language through the URL would not be a good solution. We need to give them some links on top of the pages so that they can change it at any time. In ASP.NET MVC the simplest way is to create a HtmlHelper to render the links for each language.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.Web.Routing;
   6: using System.Web.Mvc;
   7: using System.Web.Mvc.Html;
   8: using System.Threading;
   9:  
  10: namespace ShaunXu.MvcLocalization
  11: {
  12:     public static class SwitchLanguageHelper
  13:     {
  14:         public class Language
  15:         {
  16:             public string Url { get; set; }
  17:             public string ActionName { get; set; }
  18:             public string ControllerName { get; set; }
  19:             public RouteValueDictionary RouteValues { get; set; }
  20:             public bool IsSelected { get; set; }
  21:  
  22:             public MvcHtmlString HtmlSafeUrl
  23:             {
  24:                 get
  25:                 {
  26:                     return MvcHtmlString.Create(Url);
  27:                 }
  28:             }
  29:         }
  30:  
  31:         public static Language LanguageUrl(this HtmlHelper helper, string cultureName,
  32:             string languageRouteName = "lang", bool strictSelected = false)
  33:         {
  34:             // set the input language to lower
  35:             cultureName = cultureName.ToLower();
  36:             // retrieve the route values from the view context
  37:             var routeValues = new RouteValueDictionary(helper.ViewContext.RouteData.Values);
  38:             // copy the query strings into the route values to generate the link
  39:             var queryString = helper.ViewContext.HttpContext.Request.QueryString;
  40:             foreach (string key in queryString)
  41:             {
  42:                 if (queryString[key] != null && !string.IsNullOrWhiteSpace(key))
  43:                 {
  44:                     if (routeValues.ContainsKey(key))
  45:                     {
  46:                         routeValues[key] = queryString[key];
  47:                     }
  48:                     else
  49:                     {
  50:                         routeValues.Add(key, queryString[key]);
  51:                     }
  52:                 }
  53:             }
  54:             var actionName = routeValues["action"].ToString();
  55:             var controllerName = routeValues["controller"].ToString();
  56:             // set the language into route values
  57:             routeValues[languageRouteName] = cultureName;
  58:             // generate the language specify url
  59:             var urlHelper = new UrlHelper(helper.ViewContext.RequestContext, helper.RouteCollection);
  60:             var url = urlHelper.RouteUrl("Localization", routeValues);
  61:             // check whether the current thread ui culture is this language
  62:             var current_lang_name = Thread.CurrentThread.CurrentUICulture.Name.ToLower();
  63:             var isSelected = strictSelected ?
  64:                 current_lang_name == cultureName :
  65:                 current_lang_name.StartsWith(cultureName);
  66:             return new Language()
  67:             {
  68:                 Url = url,
  69:                 ActionName = actionName,
  70:                 ControllerName = controllerName,
  71:                 RouteValues = routeValues,
  72:                 IsSelected = isSelected
  73:             };
  74:         }
  75:  
  76:         public static MvcHtmlString LanguageSelectorLink(this HtmlHelper helper,
  77:             string cultureName, string selectedText, string unselectedText,
  78:             IDictionary<string, object> htmlAttributes, string languageRouteName = "lang", bool strictSelected = false)
  79:         {
  80:             var language = helper.LanguageUrl(cultureName, languageRouteName, strictSelected);
  81:             var link = helper.RouteLink(language.IsSelected ? selectedText : unselectedText,
  82:                 "Localization", language.RouteValues, htmlAttributes);
  83:             return link;
  84:         }
  85:  
  86:     }
  87: }

I created a class to store the information of the language links. This can be used to render a linkage for a language, and it also can be used if we need the selector it be an image linkage, dropdown list or anything we want as well.

The LanguageUrl method takes the main responsible for generating the information that can be used in the selector such as the URL, RouteValues, etc. It loads the RouteData and query string from the incoming request and swich the language part, then generate the URL of current page with that language so that it will render the same page with that language when the user clicked.

The LanguageSelectorLink method takes the responsible for rendering a full Html linkage for this language which we will use it for our simple exmaple.

We need the language select available in all pages so we should put the links in the master page.

   1: <div id="logindisplay">
   2:     <%
   1:  Html.RenderPartial("LogOnUserControl"); 
%>
   3:  
   4:     <%
   1: : Html.LanguageSelectorLink("en-US", "[English]", "English", null) 
%>
   5:     <%
   1: : Html.LanguageSelectorLink("zh-CN", "[??]", "??", null) 
%>
   6: </div> 

Don’t forget to import the namespace of the SwitchLanguageHelper class on top of the master page otherwise the extension method will not work.

image

 

Oops! Log On page crashed

Some web application only can be viewed once logged on, such as some CRM system used inside the company. It means before any action was performed the application should be redirected to the log on page if the user was not identitied. Let’s have a look on what will be in our sample application. Just add the Authorize attribute on the home controller.

image

Oops! It gave me a 404 error which means the application cannot find the resource for /Account/LogOn. This is because our routes. We have 2 routes registered in the system, the Localization route has 4 parttens: lang, controller, action and id; the Default route has 3 parttens: controller, action and id. The incoming request will be checked through all routes based on their rules and once it’s matched the value would be identified by that route. For example if the URL was http://localhost/en-US/Home/Index it matches the Localization route (lang = en-US, controller = Home, action = Index, id is optional). If the URL was http://localhost/ it was not match the Localization route (lang cannot be null or empty) so it matches the Default route since it allows all parttens to be null.

Now let’s have a look on this URL http://localhost/Account/LogOn, the Account could be the lang partten and LogOn could be the controller, since the action and id partten are all optional it matchs the Localization route so it means: language = Account, controller = LogOn, action = Index (by default). But there is no controller named LogOn and action named Index so it’s the reason why it returned 404 error.

Since the logon URL was redirected by the ASP.NET authorizing model which means we cannot add the language data into the URL we have to add a new route individually for it.

   1: routes.MapRoute(
   2:     "LogOn", // Route name
   3:     "Account/{action}", // URL with parameters
   4:     new { controller = "Account", action = "LogOn" } // Parameter defaults
   5: );
   6:  
   7: routes.MapRoute(
   8:     "Localization", // Route name
   9:     "{lang}/{controller}/{action}/{id}", // URL with parameters
  10:     new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
  11: );
  12:  
  13: routes.MapRoute(
  14:     "Default", // Route name
  15:     "{controller}/{action}/{id}", // URL with parameters
  16:     new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
  17: );

In front of the Localization and Default route I added a new one named LogOn, it only accept the Account controller so for this URL http://localhost/Account/LogOn the controller would be Account and action would be LogOn which is correct. Let’s have a look on the result.

image

 

Refactoring the codes

This application is a fairly simple example, like all example the microsoft provided, it only contains one project which is my website. In the real projects we might not want to organize our application in one project. We would like to separate the webiste, the controllers, the models, and maybe we need the data access and business layers in the different projects. So let's refactor my example a little bit and see what we should do then to make it localizable.

Here I just want to separte the controllers and view models out of my website project but would not create the data access and business logic layer since normally they would not be related with the localization.

Localization is the matter we should solve at the persentation layer. We should never pass any localized information from the business layer. For example, if the password was incorrect when authorizing an user at the business layer we should always return a flag (int or enum) to indicate the error instead of any error message strings.

image

I moved the controllers and models out of the my main website project and let them referenced by the webiste project. I added the necessary assemblies and built it. All worked well except my localization code under the home controller class. I set the message string into the ViewData from the resource class which defined in my website project, now it cannot be accessed through my controller project.

image

So what I should do here is to move the resource files out of the website project since it's at the bottom of the references hierarchy.

image

After moved the resource files to the new project and added the refereneces, I built it again but I got more error. This is because the accessing classes generated for the resource files are defined as "internal" by default which cannot be invoked out of the project. So what I can do is to create the new resource files for localization and update their access model to "Public".

image And this time our application works well.

image

 

Localizing messages in ViewModels

In the ASP.NET MVC application the message can be defined directly on the view pages, controllers and the view models. One of the scenario is to define the error messages on the view model classes through the attributes provided by System.ComponentModel.DataAnnotations. With the DataAnnotations attributes we can add the validation method and the error messages on the propties of the model classes through the AOP approch. For example when loggin on the user name field should be displayed as "User name" and should be mandatory. So the model would be defined like this, whichi doesn’t support localization.

   1: [Required]
   2: [DisplayName("User name")]
   3: public string UserName { get; set; }

We can defined the error messages for the Requeired attribute. And the pre-defined DataAnnotations attributes supports localization which means we can define the resource key and resource type then it will find the relevant resources and returned the content back. Assuming that I had defined 2 resources one for the display name the other for error message, then the attribute would be changed like this.

   1: [Required(ErrorMessageResourceName = "LogOnModel_UserName_Required", 
   2:           ErrorMessageResourceType = typeof(Resources.Global))]
   3: [Display(Name = "LogOnModel_UserName_Required", 
   4:          ResourceType = typeof(Resources.Global))]
   5: public string UserName { get; set; }

You might noticed that I changed the DisplayName attribute to Display attribute. This is because the DisplayName attribute does not support localization. Let's execute and see what's happen.

image

Oops! I think we are running into a lot of problems.

  • The localization doesn't work. You can see on the URL it's in Chinese version but the user name displayed in English.
  • The display name doesn't work. In my model attributes I specified its resource name but now it shown the property's name.
  • The error message was not localized.

Let's explain one by one.

For the first one, the localization didn't work at all. That is because we implemented the localization by the action filter attribute we created before. But the validation logic was performed by the default model binder which was invoked before the action filter attribute was performed. So when the model binder failed the validation and attempted to retrieve the error message from the resource files the culture of the current thread has not been changed by the action filter.

image

In order to make the localization (culture setting) being invokde before the model binder was executed we should move the localization logic to the Controller.ExecuteCode method, which is earlier than the model binder and validation. So I created a new class named BaseController and let it inherited from the abstract Controller class and then overrided the ExecuteCode method with the localization logic. Then I updated all controllers in the application to inherit from this BaseController.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Web.Mvc;
   6: using System.Threading;
   7: using System.Globalization;
   8: using System.Web;
   9:  
  10: namespace ShaunXu.MvcLocalization.Controllers
  11: {
  12:     public abstract class BaseController : Controller
  13:     {
  14:         protected override void ExecuteCore()
  15:         {
  16:             if (RouteData.Values["lang"] != null &&
  17:                 !string.IsNullOrWhiteSpace(RouteData.Values["lang"].ToString()))
  18:             {
  19:                 // set the culture from the route data (url)
  20:                 var lang = RouteData.Values["lang"].ToString();
  21:                 Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang);
  22:             }
  23:             else
  24:             {
  25:                 // load the culture info from the cookie
  26:                 var cookie = HttpContext.Request.Cookies["ShaunXu.MvcLocalization.CurrentUICulture"];
  27:                 var langHeader = string.Empty;
  28:                 if (cookie != null)
  29:                 {
  30:                     // set the culture by the cookie content
  31:                     langHeader = cookie.Value;
  32:                     Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);
  33:                 }
  34:                 else
  35:                 {
  36:                     // set the culture by the location if not speicified
  37:                     langHeader = HttpContext.Request.UserLanguages[0];
  38:                     Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);
  39:                 }
  40:                 // set the lang value into route data
  41:                 RouteData.Values["lang"] = langHeader;
  42:             }
  43:  
  44:             // save the location into cookie
  45:             HttpCookie _cookie = new HttpCookie("ShaunXu.MvcLocalization.CurrentUICulture", Thread.CurrentThread.CurrentUICulture.Name);
  46:             _cookie.Expires = DateTime.Now.AddYears(1);
  47:             HttpContext.Response.SetCookie(_cookie);
  48:  
  49:             base.ExecuteCore();
  50:         }
  51:     }
  52: }

For the second and third problem that is because the DisplayName attributes was defined on .NET 4.0 platform but currently the ASP.NET MVC runtime was built on .NET 3.5 which cannot invoke the assemblies under .NET 4.0.

If you downloaded the source code of the ASP.NET MVC 2 there is a solution named MvcFuturesAspNet4 which will create some assemblies built on .NET 4.0 and support the DisplayName attribute. Here I would like to use another approch to work around it.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.ComponentModel;
   6: using System.ComponentModel.DataAnnotations;
   7:  
   8: namespace ShaunXu.MvcLocalization.Models
   9: {
  10:     public class LocalizationDisplayNameAttribute : DisplayNameAttribute
  11:     {
  12:         private DisplayAttribute display;
  13:  
  14:         public LocalizationDisplayNameAttribute(string resourceName, Type resourceType)
  15:         {
  16:             this.display = new DisplayAttribute()
  17:             {
  18:                 ResourceType = resourceType,
  19:                 Name = resourceName
  20:             };
  21:         }
  22:  
  23:         public override string DisplayName
  24:         {
  25:             get
  26:             {
  27:                 return display.GetName();
  28:             }
  29:         }
  30:     }
  31: }

I created another attribute which wapped the DisplayName one. It will create an inner instance of the DisplayAttribute and set the resource key and type accordingly. Then when the DisplayName was invoked it will perform the DisplayAttribute.GetName method which supports localization.

So the view model part should be changed like this below.

   1: [Required(ErrorMessageResourceName = "LogOnModel_UserName_Required",
   2:           ErrorMessageResourceType = typeof(Resources.Global))]
   3: [LocalizationDisplayName("LogOnModel_UserName_Required", 
   4:                          typeof(Resources.Global))]
   5: public string UserName { get; set; }

And the let's take a look.

image

 

Summary

In this post I explained about how to implement the localization on an ASP.NET MVC web application. I utilized the resource files as the container of the localization information which provided by the ASP.NET runtime. And I also explain on how to update our solution while the project was being grown and separated which more usefule when we need to implement in the real projects.

The localization information can be stored in any places. In this post I just use the resource files which I can use the ASP.NET localization support classes. But we can store them into some external XML files, database and web services. The key point is to separate the content from the usage. We can isolate the resource provider and create the relevant interface to make it changable and testable.

 

PS: You can download the source code of the example here.

 

Hope this helps,

Shaun

 

All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.

Comments

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Anytao on 5/7/2010 11:44 AM
Too Looooooooooooooooooooooooong.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Kidd Lee on 5/7/2010 10:26 PM
Great! Thanks for sharing
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by ipad scrapbook app on 5/10/2010 10:39 AM
Hai, i really like this presentation of content. i am impressed with it. Keep this post. Thanks for sharing this with us. Keep blogging.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun on 5/11/2010 9:48 AM
Thanks for the encouragement all above. I will try my best to blog more things during my development. Really thanks.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Kevin Ortman on 6/12/2010 8:27 AM
Good stuff! Thank you for posting, Shaun.

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by premature ejaculation remedy on 7/26/2010 1:58 PM
You mention that a database could be used in place of a resource file. How would dyou implement this?
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by leel on 8/5/2010 4:25 AM
Thanks it is awesome
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Diego on 8/15/2010 1:16 AM
Great article. Very thorough and well implemented.
I was wondering if you can elaborate in terms of getting the localization information from a database instead of the resource files. Thanks!
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun on 8/17/2010 11:09 AM
@Diego In a big system the localization information should be stored in the center database rather than the resource file. In fact we can create our own resource manager to consume the database or any kinds of data source.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Tommaso on 11/28/2010 8:48 PM
Is there a way to continue to use unlocalized routes after the implementation of localization ? I receive a 404 error if I try to reach an unlocalized route...
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun on 11/29/2010 10:29 AM

@Tommaso
Not tested but I think if you add the default value of your localized routing, for example {lang}="en-us" then it will show the default English version if no language.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Tien Nguyen on 12/17/2010 8:00 AM
Nice article. I implement it on my website. It works fine on the first page (home page) but as soon as I click on a link from the menu it won't work since the route will be messed up. I suppose it's because my menu is created like this:
...
<li class="classnav"><%:Resources.Global.SiteMaster_Menu_Contact%></li>
...
so when I click on Location it will map it to http://localhost/Location/index but the OnActionExecuting method will try to map lang=location to create the culture from that.

Is there a solution for this ?

Thank you
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Marthijn on 1/12/2011 6:24 PM
Thanks!
I have one problem, I store the user's preferred language in a cookie, how would you set the default language based on that cookie value? (So the user sees url.com/zh instead of default url.com/en)
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun on 1/18/2011 2:26 PM

@Marthijn
In the sample code I created a base class for Controller and override the ExceuteCore method. In this method I retrieved the default language from the cookie and then update the route value.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Eugene on 2/18/2011 10:28 PM
There is no need to place all actions and controls before localization route. Simply add
replace your localization route with
routes.MapRoute(@"Localization",
@"{lang}/{controller}/{action}/{id}",
new { controller = @"Home", action = @"Index", id = UrlParameter.Optional },
new { lang = @"\w{2,3}(-\w{4})?(-\w{2,3})?"});
as you can see at http://www.csharp-examples.net/culture-names/ the previous constraint will match all possible specific cultures names

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Deepak on 3/3/2011 4:30 PM
Hi,
Your artical is one of the best article i ever seen.I am new to .net i need to understand some point
1.How to convert the data which is comming from DB and displaying on the view ,means dynamic Data.

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun on 3/3/2011 6:01 PM

@Deepak

It's based on the data type in database of your date time value. Basically if you set it's type as 'datatime' then you can get the DateTime value automatically from ADO.NET or Entity Framework. If you use string then you might need DateTime.Parse.

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Sean on 3/9/2011 2:26 PM
Hey, great post! Is there much change from this to MVC3?
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun on 3/9/2011 4:41 PM

@Sean
Not pretty sure but I don't think there's any breaking changes in MCV3 so this should works well I guess.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Kevin Hakanson on 4/20/2011 2:40 AM
Thanks, this got me started on solving a problem quickly.

FYI - K. Scott Allen says to avoid "App_GlobalResources from your controller code will break your unit tests."
http://odetocode.com/Blogs/scott/archive/2009/07/16/resource-files-and-asp-net-mvc-projects.aspx
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Rodney on 4/26/2011 12:53 AM
Great Post. Thanks for info. This is good but I wondered what your approaches are to actually translating the value in fields. For example, let's say I have Question Model with a "Description" property. What are your thoughts on the easiest way to take advantage of the Localization and Globalization features to get translations for the value in the Description property and not just the display name of the "Description" property?

I have a solution but am concerned about the long term implications.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Philipp Troxler on 5/12/2011 8:36 PM
Hey, great post. But i have a problem. With this solution the default redirect from web.config for 404 do not work! is there a solution?

Thanks Philipp
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Ajit on 5/21/2011 9:56 AM
Its really good .....
and would love to read...the way you teach.

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Ricardo Valencia on 6/8/2011 12:11 AM
in mvc3 routing fails because favicon.ico is included.
Fix:
In global.asax RegisterRoutes(RouteCollection routes)
add line-> routes.IgnoreRoute("favicon.ico");

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Baraa on 6/30/2011 11:15 PM
Very good article, thanks for sharing.

I just have one question : How to solve the area problem ? since the current scenario don't solve this issue, and the "resource not found" appear when i try to switch the culture in side an area?

Your help will be greatly appreciated.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Emilio on 8/2/2011 7:54 AM
Too Coooooool.
many thanks It is very clear and focused to the solution
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Sr on 8/3/2011 6:34 PM
Thank you. this is that I looking for.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Pavel on 8/3/2011 10:43 PM
Great stuff. Thanks a lot man!
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by dj Serva on 8/5/2011 9:44 PM
Great! Tks!
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Hong on 9/1/2011 12:03 PM
Hi mate, what do I need to run your sample code? I downloaded you example from the link, but it will not run and throw me error saying "Server Error in '/' Application.
The resource cannot be found.
"

Thanks
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Michael Baarz on 9/6/2011 6:43 PM
Hey,

i found this very useful too. I'm familiar with ASP.NET and new too MVC3. Your work with the Attribute and your way is very useful. And ... lol ... its not too long! To understand all the things around its good to have some more informations. Thank you!

Michael
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Akhilesh Yadav on 9/20/2011 10:52 PM
Excellent.. I recently started working on implementing localization in my project. This is perhaps the best link I've come across that made things really clear for me to understand. Keep blogging Shaun.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shadi on 10/1/2011 5:32 PM
nice walk-through,really helpful

I'm trying to build this project using MVC 3 but i keep getting this error

Compiler Error Message: CS1501: No overload for method 'LanguageSelectorLink' takes 4 arguments


Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Fabio Shiomi on 11/20/2011 12:35 AM
Great! Thanks for sharing :)))))))
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Melick on 11/28/2011 2:56 PM
Very good Article
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by ori on 1/13/2012 5:07 AM
Great post!

I would like to ask how can i use the info from the url and setup the current culture in the httpmodule ?

http://stackoverflow.com/questions/8842182/mvc-localication-set-culture-in-httpmodule

Thank you
Ori

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun on 1/13/2012 3:29 PM
@ori

HttpModule is another way to implement the localization. The theory would be very similar which split the incoming request and get the culture info out. I don't have an example on using HttpModule for localization.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Eric on 2/20/2012 2:08 PM
Great job! I found this article just in time. You've saved my day!
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Bert on 2/26/2012 2:57 AM
Nice, Thanks for the help, appreciate it!
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by johnny on 3/6/2012 5:31 PM
Thank you so much, this is really really really useful man :-)! For dealing with localizations as well as with the MVC infrastructure pieces, like ActionFilters and Controller.Execute etc. Thank you man, keep writing stuff like this :o), Andy
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by HJP on 4/12/2012 4:56 AM
That's a really helpful post. I've been having problems to have users create their accounts. I'm using the razor syntax. I did not have the same kind of error message (Provider encountered an unknown problem) as shown in your example, but I think I've been running on a localisation problem. The fact is when I tested it with WebMatrix, everything was fine. I got the probleem after deployment.
Thanks for that post
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by vietnam online on 4/13/2012 4:35 PM
Thank for your useful tutorial. I had tried many way, but I couldn't do my project. After found this post, I've finished my problem.
Thank!
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Colau on 4/17/2012 11:12 PM
Hi, when i download your project and start debbuging I cant open any view. I have to do something more to can open and test your solution?

Thanks a lot.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Hamed on 5/8/2012 10:30 PM
Many thanks for your full description & simple ( but optimized ) solution for this job.
Thanks Shaun
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by dondonson on 6/12/2012 10:21 PM
Yeah, I also have to ask: What about areas? Your solution did not work very well for me...
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Philipp on 6/13/2012 5:33 AM
Hi, have you tested this solution with mvc 4 and bundeling? in my project it dosent work!
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun Xu on 6/13/2012 9:24 AM
@dondonson
@Philipp

I didn't tried this solution in Areas, I guess we need some tweaks in route as the Area is built based on routing.

Regarding the MVC 4 I'm not sure if there any breaking changes affect this sample. I didn't tested in MVC4.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by samthc on 7/4/2012 11:32 PM
There is something completly wrong!!!
The code shown in this article does match with the source code that can be downloaded, foreaxmple:

class LocalizationAttribute : ActionFilterAttribute...

Above code is not to be found any where in the source code.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by samthc on 7/4/2012 11:39 PM
One more thing.
When I run the source code I get error saying resource cannot be found:
http://localhost:34763/Views/Home/Index.aspx

I do not know what to say about this article, I just think that you obviously need to improve some things.

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun Xu on 7/6/2012 3:25 PM
samthc,

Sorry for the late response. I cannot reach my attachment currently since the skydrive was blocked in my company. I will have a look when I have the time back home. But if read the end of the article I think the LocalizationAttribute was obsolete since I need to use the ContollerBase.ExecuteCore to update the route data. My code attached was the final version so this might be the reason that the LocalizationAttribute was not there.

Ref your second question, in MVC you should use http://localhost/Home/Index to view the pages. The *.aspx file were just the view template that you cannot open then directly from the browser. This is the reason why you got an 404 error when you went to http://localhost/Views/Home/Index.aspx.

HTH,
Shaun
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Gwen on 7/10/2012 10:48 PM
Hi, in the part "Links for the language selection" you said : This can be used to render a linkage for a language, and it also can be used if we need the selector it be an image linkage.
How can we use an image linkage to change the language?
I try this but It doesn't work :
<a href=" <%=Html.LanguageSelectorLink("fr-FR", "[Français]", "Français", null)%>">
<img src="flag_france.png" />

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun Xu on 7/11/2012 9:58 AM
Gwen,

Well it's long time ago since I wrote this one. Let me try my best to remember what I said and how MVC works. About 2 years haven't used MVC.

Mmm... I think your approach is not correct. I used the extension method of LanguageSelectorLink to render the language linkage. So if you want to use image, you probably need to set your image HTML tags inside the LanguageSelectorLink parameters "selectedText" and "unselectedText". I didn't test since I don't have the code available. But I guess this could be work.

Hope this helps,
Shaun
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Gwen on 7/11/2012 3:28 PM
Thank you for your answer, I know that you write this since a long time.
If I understand what you said, I try something like this:
<%=Html.LanguageSelectorLink("fr-FR", "<img src=" + '"' + "flag_france.png" + '"' + "/>", "<img src=" + '"' + "flag_france.png" + '"' + "/>", null)%>
But it doesn't work because html is not interpreted :(
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun Xu on 7/11/2012 4:02 PM
Hi Gwen,

Sorry I don't have the time currently to figure this out for you. If my solution doesn't work, you might have to modify the LanguageSelectorLink method. I guess this was because I used the Html.RouteLink method which encodes the text. I will have a look when I have the time but for now, I'm sorry I might not be help you.

Shaun
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Gwen on 7/11/2012 4:04 PM
Ok, I understand, thank you for answering. I think too that the problem come from RouteLink so I will investigate for another solution.
Thank you
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Wang on 7/28/2012 2:42 AM
Hi Shaun, Thanks a lot for the demo, it really help, I am following your instructions, as I am new in MVC, but I am stucked on screen 5, you mentioned:
"The title and the description are defined in the view page so we will change the view page. It will load the content through the access class generated by Visual Studio."
Could you please more specific how to create this? Should I create a new ViewPage.aspx? or create a new View? What name should I call it if I need create one them? under which folder?
I tried a new ViewPage1.aspx under root of my project, and pasted your code, and finished the codes before screen 10, I test it, I only got the data of "HomeIndex_Message" , I think I did not wrong in screen 5, could you please help? thanks a lot,


Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun on 7/28/2012 12:15 PM
@Peter Wang,

You don't need to create a new page. What I mentioned was that you just need modify the current home page, under the View folder.

Remember, in MVC the *.aspx file was NOT the original ASP.NET WebForm page, it's something like a template. So you should never create ASP.NET Web Form in MVC, instead you'd better create a new View and the related controller.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Wang on 7/29/2012 2:07 AM
Hi Shaun, Thanks a lot for your quick response,
OK, as I created the MVC project based on the tamplate MVC 3, so I think the Home view is:Index.cshtml under Views/Home, the default code of this view is as follows:
####################################
@{
ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit http://asp.net/mvc.
</p>
#########################################
So I think I should replace this codes with your code on screenshot 5, but, I got compile error after pasted your code.
I also see the first line of your codes have:<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

But I do not have Site.Master and ViewPage, (it seems this is the code for Webform, but my project is MVC), could you please tell me what is wrong ? thanks a lot,

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Wang on 7/29/2012 6:06 AM
Hi Shaun, I tried to modified my home view Index.cshtml under Views/Home to these codes:
<p>
<%: Resources.Global.HomeIndex_Title %>
</p>

<h2>@ViewBag.Message</h2>
<p>
<%: Resources.Global.Home_Index_Desc %> http://asp.net/mvc.
</p>

Basically, I replaced the original codes as I mentioned in above post to this codes.
But it only displays the <h2>@ViewBag.Message</h2>, the rests do not show, can you tell me what is wrong with my codes? Thanks
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Wang on 7/29/2012 6:09 AM
Sorry, the last post missed the codes, this the entire codes:
<h2>@ViewBag.Message</h2>
<p>
<%: Resources.Global.Home_Index_Desc %> http://asp.net/mvc.
</p>
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun Xu on 7/30/2012 9:49 AM
@Peter

I think you are using Razor view engine in your MVC3 project. But my sample was in MVC2 (or maybe 1 I forgot). In MVC3 you'd better use @Resource.Global.Home_Index_Desc.

Alternatively, you can create another MVC3 project with ASP.NET Form view engine rather than the default Razor engine. Then you can use the code I mentioned in this post I think.
Gravatar # re: LocalizationI in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Wang on 7/30/2012 10:32 AM
Hi Shaun, Thank you so much for your quick response,
that works.
I also found this link: http://code52.org/aspnet-internationalization/tutorial.html
which is another way to implement internationalization, have you used the codes52 before? what is your opinions if I use it?
As I have many mvc4 views(page) with the SQL table data in it, so I think I can not use this way - Resources, I think I should use different views(pages) to switch to English and French, do you know how to implement the code52 in this way? as that link does not show this. thanks
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun Xu on 7/30/2012 10:53 AM
@Peter

I've never used the code52. So I'm not sure how it will be in your project. But as I mentioned in my post, using resources is just one of the approaches. You can store your localized data in any data store, of course the SQL. But you need to implement the ResourceManager or some infrastructure so that it can give the proper value based on the culture. The key point of localization is to remove the actual data from your application. Using resource is just one choice.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Wang on 7/31/2012 9:32 AM
Hi Shaun,
I have written the SwitchLanguageHelper class , in MVC3, instead of Master page, I should use _Layout.cshml view, but you mentioned

"Don’t forget to import the namespace of the SwitchLanguageHelper class on top of the master page otherwise the extension method will not work."

How to add it in the beginning of _Layout.cshml? I tried @using SwitchLanguageHelper, it does not work,
(By the way, I have refacting the code as you mentioned to make Models, Controllers and Resources to seperate project file), but I think the SwitchLanguageHelper is under the same project with _Layout.cshml, so @using SwitchLanguageHelper should work, but it does not work, any idea?
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun Xu on 7/31/2012 9:51 AM
@Peter

Please refer this page
http://stackoverflow.com/questions/3239006/how-to-import-a-namespace-in-razor-view-page
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Wang on 7/31/2012 10:16 AM
Thanks a lot,
I am using @using ShaunXu (as my project name is "ShaunXu" and the namespace in SwitchLanguageHelper class is "ShaunXu",
After added @using ShaunXu in _Layout.cshtml, it works for the two language links only, I have compile error after I added @Html.RenderPartial("LogOnUserControl"),
Any reason why?
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Wang on 8/1/2012 1:28 AM
Hi Shaun, Thanks for your quick response,
In MVC 4, the Gloal.asax.cs is different than the same code in MVC3, these are the code in MVC4:
########################
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
#################
As I am using MVC4, so I have to customize your code to make it work in MVC4, Could you please help me how to customize your code to make it working on MVC4?
Thanks
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Jay on 8/8/2012 6:37 AM
this is an awesome explanation. keep up the good work
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Wang on 8/23/2012 3:27 AM
HI Shaun,
I am using MVC 4 with _Layout.cshtml shared view, how to convert your code of ": Html.LanguageSelectorLink("en-US", "[English]", "English", null) "
to make it working on _Layout.cshtml view?
I copied your code to _Layout.cshtml, it does not show up, you may use webforms? I am using MVC.
Thanks
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Wang on 8/24/2012 3:07 AM
Hi,
I am trying to use this code: @Html.LanguageSelectorLink("en-US", "[English], "English", null)
In my _Layout.cshtml page, but I got red line under it, it says "No overload for method 'LanguageSelectorLink' takes 2 arguments", I can see in SwitchLanguageHelper.cs class, the LanguageSelectorLink takes 7 arguments. But in your example, you used: <% : Html.LanguageSelectorLink("en-US", "[English], "English", null) %>
Could you please what should I change in my case? thanks.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Willy on 8/26/2012 1:15 AM
Hi, your article is great and I followed your way to have self study. Unfortunately, I am facing same issue about incorrect no of arguments in LanguageSelectorLink. I did change the statement into razor format as following. Any advise?

@SwitchLanguageHelper.LanguageSelectorLink("en-US", "[English]", "English", null)

Besides, I have another issue that NOT all the resources text showed on same page switch to related culture language but only the one in html title. Do you know why?

<My configuration>
I am using MVC3 with razor view engine. I changed it
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Sruti on 8/30/2012 6:34 PM
Helpful post!

To add to this, if it is MVC3, we can just change the locale at run-time on Global.asax and simply use <%=ResourceFileIdentifier.ResourceKey%> in the aspx page.

We can also use the DisplayName attribute. The MVC framework uses resx file name conventions to find resources for a given locale.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Peter Cong on 9/14/2012 8:04 AM
Hi Shaun,
Finally, I make it working,
In your codes, you are using cookie in server side code, if client may disable cookies in their machine, so could you tell me another way to replace cookie which can have same function as cookie? such session, or tables? thanks
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Jane Etolo on 10/22/2012 1:29 AM
Is there any way to use resources dynamically with database as resource provider? Something like the syntax for the Tausens Localization library at http://www.tausens.com/using-the-localization-library as an extension for that stuff you've provided.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Shaun Xu on 10/22/2012 7:52 AM
Jane Etolo
Please have a look on the second version of this post here http://wblo.gs/dB9, hope that helps.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Gerardo on 12/22/2012 2:55 AM
He was using a solution and I found a problem with the areas. Would you have any example with areas?
Thank you.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by tpyo on 12/30/2012 12:51 PM
I salute you sir, that's a _fine_ write up with your full workings displayed for all to observe and learn. I'll now read the update. I really appreciate the work you put into this, thanks. :)
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Tram Tri on 2/6/2013 7:24 PM
This article have got me out of my problem. Thanks for sharing. And it's maybe change my way of programming that puts all code inside a project. Please keep your sharing up.
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Tram Tri on 2/7/2013 10:05 PM
I got into another problem when I try to follow your code. I got a red underline at "helper.RouteLink" where helper is a HtmlHelper object, exactly at LanguageSelectorLink function. Could you help me. Thanks a lot
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Altair on 2/22/2013 5:22 AM
I downloaded the source code, but cannot run the project. Got the error "Resource cannot be found", and no more details are provided. I see that the App_Data folder is empty, so probably the aspnetdb.mdf is mising
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by John Jin on 2/27/2013 7:39 AM
This is great post. I will implement this to my project. Thanks...
To those have questions, please check you code carefully before you raise questions.

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by fro9000 on 4/19/2013 7:53 PM
Hi Shaun
Thank you for sharing this great article. I sure it saves me hours.
I modified the routeconfig with a special area for changing the language as follow [area setLng]:

routes.MapRoute(
name: "Localization", // Route name
url: "setLng/{lang}/{controller}/{action}/{id}",
defaults: new { controller = "Customer", action = "blablabla", id = UrlParameter.Optional }
);

Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by co on 6/6/2013 5:08 PM
this is too long:S
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by Laurent Jordi on 9/23/2013 5:24 PM
Localization : next level...

Hi all, our community is working on an open source multicultural asp.net mvc 4 framework including cms features (http://myprettycms.codeplex.com for sources and http://community.innovacall.net for testing).

Our application is a two in one, there is content and business features.

We use localized friendly url.

I have an issue for separation of content (and main menu) culture and UI culture.

I mean, if you are authentified, you did select a favorite language during registration process.

If you want to see an english content but your favorite language is french, I want the content to be displayed in english but all UI specific (Dialog boxes, form fields, message) items to be in french.

We will release the project in a fiew days and we did not solve the dual-localization problem.

Could you help us ?

Thanks a lot

Laurent
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by sharath on 2/8/2014 3:25 AM
thanx shaun, very good article, please keep writing.
Gravatar # Test
Posted by Vinay on 6/18/2014 2:50 PM
Hello this is testing of loc Gob
Gravatar # re: Localization in ASP.NET MVC – 3 Days Investigation, 1 Day Job
Posted by ossprologix on 6/25/2014 12:44 PM
exactly what i was looking for(thumbs up!!)
Post A Comment
Title:
Name:
Email:
Comment:
Verification: