ASP.NETMVC、本地化路由和用户默认语言我使用的是ASP.NETMVC本地化路由。因此,当用户访问英文站点时,它是example.com/en/Controller/Action,而瑞典站点是example.com/sv/Controller/Action。您如何确保当用户进入网站时他/她直接使用正确的语言?我知道如何获得我想要的语言,这不是问题。我过去所做的是将文化放入RegisterRoutes方法中。但是由于我的页面是集成模式,所以我无法从Application_Start获取请求。那么我应该如何确保路线从一开始就是正确的呢?我就是做这个的。~~免责声明:伪代码~~global.asaxpublicstaticvoidRegisterRoutes(RouteCollectionroutes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");routes.IgnoreRoute("{*favicon}",new{favicon=@"(.*/)?favicon.ico(/.*)?"});routes.MapRoute("Question-Answer",//路由名称"{languageCode}/{controller}/{action}",//带参数的URLnew{controller="home",action="index"}//Parameter默认值);注意:控制器和/或动作不需要是第一和第二。事实上,他们根本不需要urlwithparameters部分中存在的urlwithparameters。然后...HomeController.cspublicActionResultIndex(stringlanguageCode){if(string.IsNullOrEmpty(languageCode)||languageCode!=avalidlanguagecode){//没有提供代码或者我们没有收到有效代码//你无法处理...所以将它们发送到404页面。//returnResourceNotFoundView...}//..dowhateverinhere..}额外的建议你也可以在你的路由中添加路由约束,这样它只接受一些字符串作为languageCode参数。所以偷了这家伙的代码....(更多伪代码)...}私有字符串[]_values;publicboolMatch(HttpContextBasehttpContext,Routeroute,stringparameterName,RouteValueDictionaryvalues,RouteDirectionrouteDirection){//从名为“value”的RouteValueDictionary中获取名为“parameterName”的值stringvalue=values[parameterName].ToString();//返回true是允许值列表包含//这个值。返回_values.Contains(值);}}意味着你可以这样做......,action="index"}//参数默认值new{languageCode=newFromValuesListConstraint("en","sv",..etc)});好了:)我为MVCApi版本控制做了类似的事情。GL:)希望这会有所帮助。好的..另一个建议。只是为了确保我理解,您想...如果是这样...这个答案分为三个部分:-添加路线。(这是我之前回答的剪切和粘贴)。global.asaxpublicstaticvoidRegisterRoutes(RouteCollectionroutes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");routes.IgnoreRoute("{*favicon}",new{favicon=@"(.*/)?favicon.ico(/.*)?"});routes.MapRoute("Question-Answer",//路由名称"{languageCode}/{controller}/{action}",//带参数的URLnew{controller="home",action="index"}//Parameter默认值);更新(根据评论)所以如果你想要路由http://www.example.com/sv/account/logon那么上面的路由将起作用。LanguageCode==sv(orenorfrorwhateverlanguageyousupport)account==controller:AccountControllerlogin==action.我说的controller="home"和action="index"只是意味着那两个参数默认为那些没有提供的值。因此,如果您转到http://www.example.com/sv/account/logon,那么MVC框架足够聪明,可以知道(基于该路由)languageCodeparamters==sv,controller==actionandaction(方法)==索引。注意:路线的顺序很重要。很重要。当您注册一条路线时,这条路线必须(如果不是)第一条路线(在IgonoreRoute之后)。您需要创建一个自定义ActionFilter,它将在执行操作之前调用。这是我的快速尝试......使用System.Linq;使用System.Web.Mvc;namespaceYourNamespace.Web.Application.Models{publicclassLanguageCodeActionFilter:ActionFilterAttribute{//这会检查当前的语言代码。如果缺少一个,它默认它。publicoverridevoidOnActionExecuting(ActionExecutingContextfilterContext){conststringrouteDataKey="languageCode";conststringdefaultLanguageCode="sv";varvalidLanguageCodes=new[]{"en","sv"};//确定语言。if(filterContext.RouteData.Values[routeDataKey]==null||!validLanguageCodes.Contains(filterContext.RouteData.Values[routeDataKey])){//添加或覆盖语言代码值。如果(filterContext.RouteData.Values.ContainsKey(routeDataKey)){filterContext.RouteData.Values[routeDataKey]=defaultLanguageCode;}else{filterContext.RouteData.Values.Add(routeDataKey,defaultLanguageCode);}}base.OnActionExecuting(filterContext);}}}现在你需要创建一个BaseController,你的所有控制器都继承ce它然后创建一个易于访问的属性,您的所有操作都可以访问...然后根据该值显示他们想要的任何内容。我们开始了……(又是伪代码……)然后我们装饰我们的:)[LanguageCodeActionFilter]publicclassApiController:BaseController{publicActionResultIndex(){if(this.LanguageCode=="sv")...//whatever..etc..}}注意如何我当然装饰了……不只是一举一动。这意味着该类中的所有操作都将受到ActionFilter的影响:)此外,您可能希望在global.asax中添加一个新路由来处理NOlanguageCode..同时对默认值进行硬编码......就像(也未经测试)。..…routes.MapRoute("Question-Answer",//路由名称"{controller}/{action}",//带参数的URLnew{controller="home",action="index",languageCode="sv"}//参数默认值);这有帮助吗?我知道这是一个非常古老的问题,但只需解决一整套相关问题,我想我会分享我的解决方案。下面是一个完整的解决方案,包括一些轻松更改语言的额外技巧。它允许特定的文化,而不仅仅是特定的语言(但在这个例子中只保留了语言部分)。该功能包括:第1步:修改RouteConfig中的RegisterRoutes这个新路由包括一个约束(正如其他人也建议的那样)以确保语言路由不会获得某些标准路径。不需要默认语言值,因为它全部由LocalisationAttribute处理(请参阅步骤2)。publicstaticvoidRegisterRoutes(RouteCollectionroutes){...//特殊本地化路由映射-期望特定语言/文化代码作为第一个参数routes.MapRoute(name:"Localisation",url:"{lang}/{controller}/{action}/{id}",默认值:new{controller="Home",action="Index",id=UrlParameter.Optional},constraints:new{lang=@"[az]{2}|[az]{2}-[a-zA-Z]{2}"});//默认路由routes.MapRoute(name:"Default",url:"{controller}/{action}/{id}",defaults:new{controller="Home",action="Index",id=UrlParameter.选修的});第2步:创建本地化属性这将在处理请求之前查看控制器请求,并基于URL、cookie或默认浏览器Culture更改当前文化。//基于:http://geekswithblogs.net/shaunxu/archive/2010/05/06/localization-in-asp.net-mvc-ndash-3-days-investigation-1-day.aspx公共类LocalisationAttribute:ActionFilterAttribute{publicconststringLangParam="lang";publicconststringCookieName="mydomain.CurrentUICulture";//此应用程序中允许的语言列表(以加快检查速度)privateconststringCultures="en-GBen-USde-DEfr-FRes-ESro-RO";publicoverridevoidOnActionExecuting(ActionExecutingContextfilterContext){//尝试先从URL获取文化varculture=(string)filterContext.RouteData.Values[LangParam];//如果未提供,或者文化与已知文化列表不匹配,请尝试cookie或浏览器设置if(string.IsNullOrEmpty(culture)||!Cultures.Contains(culture)){//从cookievarcookie=filterContext.HttpContext.Request.Cookies[CookieName];if(cookie!=null){//通过cookie内容设置文化文化=cookie.Value;}else{//如果未指定,则按位置设置文化culture=filterContext.HttpContext.Request.UserLanguages[0];}//将lang值设置到路由数据中filterContext.RouteData.Values[LangParam]=culture;}//将“-”之前的部分作为主要语言varlanguage=culture.Split(newchar[]{'-'},StringSplitOptions.RemoveEmptyEntries)[0];filterContext.RouteData.Values[LangParam]=语言;//设置语言-现在忽略特定文化Thread.CurrentThread.CurrentUICulture=CultureInfo.CreateSpecificCulture(language);//将语言环境保存到cookie中(完整语言环境)HttpCookie_cookie=newHttpCookie(CookieName,culture);_cookie.Expires=DateTime.Now.AddYears(1);filterContext.HttpContext.Response.SetCookie(_cookie);//传递给正常的控制器处理base.OnActionExecuting(filterContext);第3步:本地化应用于所有控制器,例如[Localisation]第4步:更改语言(例如从菜单)这有点棘手,需要一些解决方法将ChangeLanguage方法添加到您的帐户控制器。这将从“先前路径”中删除所有现有语言代码,以使新语言生效。//Regex仅查找URL的语言代码部分-语言(aa)或语言环境(aa-AA)语法staticreadonlyRegexremoveLanguage=newRegex(@"/[az]{2}/|/[az]{2}-[a-zA-Z]{2}/",RegexOptions.Compiled);[AllowAnonymous]publicActionResultChangeLanguage(stringid){if(!string.IsNullOrEmpty(id)){//解码返回URL并从中删除任何语言选择器id=Server.UrlDecode(id);id=removeLanguage.Replace(id,@"/");返回重定向(id);}返回重定向(@"/");}第5步:添加了LanguageMenuLinks菜单选项,其中包含指定为路径参数的新语言的链接。例如(Razor示例)@Html.ActionLink("English","ChangeLanguage","Account",new{lang="en",id=HttpUtility.UrlEncode(Request.RawUrl)},null)@Html.ActionLink("Spanish","ChangeLanguage","Account",new{lang="es",id=HttpUtility.UrlEncode(Request.RawUrl)},null)返回当前页面的url,编码后它可以是URL的id参数。这意味着您需要启用某些转义序列,否则Razor将拒绝这些转义序列作为潜在的安全违规行为。注意:对于非剃须刀设置,您基本上需要一个具有新语言和当前页面相对URL的锚点,如下所示:http://website.com/{language}/account/changelanguage/{existingURL}:http://website.com/{language}/account/changelanguage/{existingURL}语言http://website.com/{language}/account/changelanguage/{existingURL}account/http://website.com/{language}/account/changelanguage/{existingURL}其中{language}是新的文化代码,{existingURL}是当前相关页面地址的URL编码版本(因此我们将返回到选择新语言的同一页面)。第6步:在url中启用某些“不安全”字符返回URL所需的编码意味着您需要在web.config中启用某些转义字符,否则现有的URL参数将导致错误。在您的web.config中,找到httpRuntime标记(或添加它)并向其中添加以下内容(基本上删除该属性的标准版本中的%):requestPathInvalidCharacters="<,>,&,:,,?"中web.config,找到该部分并在其中添加以下内容:如果url格式正确,您可以在global.asaxBeginRequest中询问。您也可以尝试使用路由,但根据我的经验,如果您不确定第一个参数是lang,您的路由将非常不稳定。SubApplication_BeginRequest(ByValsenderAsObject,ByValeAsEventArgs)DimlangAsString="es"如果不是Request.Path.ToLower.StartsWith("sv/")and_notRequest.Path.ToLower.StartsWith("en/")''//向浏览器询问首选语言SelectCaseMid(Request.UserLanguages(0).ToString(),1,2).ToLowerCase"en"Response.Redirect("en/")Case"sv"Response.Redirect("sv/")CaseElseResponse.Redirect("sv/")''//默认的EndSelectendifendsub未经测试的代码。原谅我的VB。以上就是C#学习教程的全部内容:ASP.NETMVC、本地化路由和用户默认语言。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注---本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
