-
-
根据语言代码设置当前区域性(如果存在)
-
您需要定义路由映射,以便只要URL上有语言代码,它就会被放入路由数据集合中。
您可以在
RouteConfig
:
namespace DL.SO.Globalization.DotNet.Web.UI
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.LowercaseUrls = true;
routes.MapRoute(
name: "DefaultWithLang",
url: "{lang}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { lang = new LanguageRouteConstraint() }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
我们将回到route约束,但这里的想法是先运行这个“DefaultWithLang”映射,看看传入的请求是否附加了语言代码。如果是,请使用键将其保存到路由集合
lang
. 否则,请按正常方式处理。
假设我们定义了这两个映射,传入的请求看起来像
/home/index
. 如果没有该路由约束,它将映射到“DefaultWithLang”,其中
朗
是“家”,这是不正确的。
我们需要一种方法来测试语言代码是否是有效的2字母代码。为此,可以创建管线约束:
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Routing;
namespace DL.SO.Globalization.DotNet.Web.UI.RouteConstraints
{
public class LanguageRouteConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName,
RouteValueDictionary values, RouteDirection routeDirection)
{
return Regex.IsMatch((string)values[parameterName], @"^[a-z]{2}$");
}
}
}
2根据语言代码设置当前区域性(如果存在)
现在我们知道语言代码将被放入路由数据收集中。我们可以在此基础上设置当前线程的当前区域性和当前UI区域性。
ActionFilter
:
namespace DL.SO.Globalization.DotNet.Web.UI.Filters
{
public class LanguageFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var values = filterContext.RouteData.Values;
string languageCode = (string)values["lang"] ?? "en";
var cultureInfo = new CultureInfo(languageCode);
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultureInfo.Name);
}
}
}
在这里,我从路由数据收集中读取语言代码值,如果不存在,则默认为“en”。
要在整个应用程序中启用它,可以将其添加到
FilterConfig.cs
:
namespace DL.SO.Globalization.DotNet.Web.UI
{
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new LanguageFilter());
filters.Add(new HandleErrorAttribute());
}
}
}
三。如果出现语言代码,请将请求路由到本地化视图
与步骤2类似,现在我们有了语言代码,我们需要创建一个自定义视图引擎,将请求路由到不同的视图:
namespace DL.SO.Globalization.DotNet.Web.UI
{
public class GlobalizationRazorViewEngine : RazorViewEngine
{
protected override IView CreatePartialView(ControllerContext controllerContext,
string partialPath)
{
partialPath = GetGlobalizeViewPath(controllerContext, partialPath);
return base.CreatePartialView(controllerContext, partialPath);
}
protected override IView CreateView(ControllerContext controllerContext,
string viewPath, string masterPath)
{
viewPath = GetGlobalizeViewPath(controllerContext, viewPath);
return base.CreateView(controllerContext, viewPath, masterPath);
}
private string GetGlobalizeViewPath(ControllerContext controllerContext,
string viewPath)
{
var request = controllerContext.HttpContext.Request;
var values = controllerContext.RouteData.Values;
string languageCode = (string)values["lang"];
if (!String.IsNullOrWhiteSpace(languageCode))
{
string localizedViewPath = Regex.Replace(viewPath,
"^~/Views/",
String.Format("~/{0}/Views/", languageCode)
);
if (File.Exists(request.MapPath(localizedViewPath)))
{
viewPath = localizedViewPath;
}
}
return viewPath;
}
}
}
这里的逻辑应该是直截了当的:如果语言代码存在,尝试将其附加到MVC应用程序将用来查找相应视图的原始视图路径。
注意
_viewStart.cshtml
以及
web.config
从原来的
Views
新本地化的文件夹
意见
~/Views
文件夹。
Application_Start()
:
namespace DL.SO.Globalization.DotNet.Web.UI
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new GlobalizationRazorViewEngine());
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
截图
与
zh/
在URL上:
文件夹结构:
Github源代码:
https://github.com/davidliang2008/DL.SO.Globalization.DotNet/tree/master/DL.SO.Globalization.DotNet.Web.UI