I. Localization support for ASP.NET mvc
asp.net MVC is run based on ASP.net, so all the features provided by ASP.net can be used in MVC, such as caching, session state, and localization. In the traditional ASP.net Web Forms era We use resource files to store content in different languages and retrieve them using ResourceManager classes that are automatically generated by Visual Studio. They are just as effective in asp.net mvc.
Let me create a standard asp.net MVC example application. The site is in Chinese and we can see that all the content is written in the view and controller class.
The framework I use is the MVC3 Razor template based Web site.
Create a MVC3 Web application using Visual Studio 2010, select the Internet application in the selection that appears, and the view engine is razor;
It can be seen that the site is now in Chinese, and we can see that all the content in the view and the controller are hard-coded.
What I need to do now is to separate all the content from the page and the controller, asp.net give us a file called App_GlobalResources, which contains global resource files for various languages. We just need to right-click on a Web project in Solution Manager and add-> to the ASP.net folder->app_globalresources
I created the Chinese and English two languages resource files, Chinese is the default language of the program, so I first create Global.resx file, then Global.en.resx, the middle of "en" is the English culture Name. If you need French, then you only need to create Global.fr.resx files, and Visual Studio will automatically generate the corresponding classes.
Now let me add some content to the resource file, where we need to replace three places: title, message and description, so we add 3 items to the two resource files.
The title and description are defined in the view page, so I'll change the view.
Copy Code code as follows:
@{
Viewbag.title = Resources.Global.Home_Index_Title;
}
<p>
@Resources. Global.home_index_desc
<a href= "Http://asp.net/mvc" title= "@Resources. Global.home_index_desclink" >http://asp.net/mvc</a>.
</p>
Copy Code code as follows:
Public ActionResult Index ()
{
Viewbag.message = Resources.Global.Home_Index_Message;
return View ();
}
Specify the language by URL
We have moved the content to the resource file, but our program does not support localization because there is no place where we can set the specified language. For the sake of simplicity, we will use the URL to indicate the language of choice (similar to the Microsoft Web site), meaning that if my URL is http://localhost/en-US/Home/Index, then the site will be reflected in English; and http://localhost/ Zh-cn/home/index is Simplified Chinese. The user can change the language on any page that stays on, and the language settings are preserved when he wants to share the URL.
To achieve the effect, I changed the route of the program, adding a routing rule named "Lang" at the top:
Copy Code code as follows:
public static void RegisterRoutes (RouteCollection routes)
{
Routes. Ignoreroute ("{resource}.axd/{*pathinfo}");
Routes. Maproute (
"Localization",//Routing name
' {lang}/{controller}/{action}/{id} ',//URL with parameter
New {controller = "Home", action = "Index", id = urlparameter.optional}//parameter default value
);
Routes. Maproute (
' Default ',//Routing name
' {controller}/{action}/{id} ',//URL with parameter
New {controller = "Home", action = "Index", id = urlparameter.optional}//Parameter defaults
);
}
Note that the default value for Lang is not set in the code, and the default route is not removed, which prevents the program from parsing, such as Http://localhost/and Http://localhost/Home/Index addresses.
Because we need the URL to set the language, we need to perform the write logic before each action executes, where Actionfilter will be a good solution.
Copy Code code as follows:
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Web;
Using SYSTEM.WEB.MVC;
Using System.Threading;
Using System.Globalization;
Namespace Shaunxu.mvclocalization
{
public class Localizationattribute:actionfilterattribute
{
public override void OnActionExecuting (ActionExecutingContext filtercontext)
{
if (filtercontext.routedata.values["lang"]!= null &&
!string. Isnullorwhitespace (filtercontext.routedata.values["Lang"). ToString ()))
{
Set the language from the routing data (URL)
var lang = filtercontext.routedata.values["Lang"]. ToString ();
Thread.CurrentThread.CurrentUICulture = cultureinfo.createspecificculture (lang);
}
Else
{
Reading language settings from cookies
var cookie = filtercontext.httpcontext.request.cookies["ShaunXu.MvcLocalization.CurrentUICulture"];
var langheader = string. Empty;
if (cookie!= null)
{
Set Language according to Cookie
Langheader = cookie. Value;
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture (Langheader);
}
Else
{
Set the default language if read cookies fail
Langheader = Filtercontext.httpcontext.request.userlanguages[0];
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture (Langheader);
}
Set the language value to the route value
filtercontext.routedata.values["lang"] = Langheader;
}
Save the settings in a cookie
HttpCookie _cookie = new HttpCookie ("ShaunXu.MvcLocalization.CurrentUICulture", Thread.CurrentThread.CurrentUICulture.Name);
_cookie. Expires = DateTime.Now.AddYears (1);
FilterContext.HttpContext.Response.SetCookie (_cookie);
Base. OnActionExecuting (Filtercontext);
}
}
}
I created a "Localizationattribute" that inherits from ActionFilterAttribute and writes the properties of the OnActionExecuting method, first checking the values in the route, if the language setting is included, Sets the current zone value of the current process, indicating that the resource manager (Visual Studio is automatically generated from the resource file) gets the associated value. If the language value in the route is not found, the cookie value is read to set, otherwise the default language is used. Finally put the value in the route and save it in the cookie.
I use this property in the home controller so that all the action can perform my localization logic.
Copy Code code as follows:
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Web;
Using SYSTEM.WEB.MVC;
Using Showlocal.models;
Namespace Showlocal.controllers
{
[Localization]
public class Homecontroller:controller
{
Public ActionResult Index ()
{
Viewbag.message = Resources.Global.Home_Index_Message;
return View ();
}
Public ActionResult About ()
{
return View ();
}
}
}
Select we can start the site and then add the language to see the results on the URL