MVC数据标注层:set CurrentUICulture 语句放在哪里?
-
19-09-2019 - |
题
我对 MVC 应用程序的本地化感到着迷。
后 我最近的一个问题 我遵循了这种方法:
- 语言存储在 Session["lang"] 中
- 每个控制器都继承自我自己的BaseController,它重写了OnActionExecuting,并在这个方法中读取Session并设置CurrentCulture和CurrentUICulture
在数据注释层出现之前,这非常有效。似乎它在执行操作本身之前被调用,因此它总是以默认语言获取错误消息!
字段声明如下:
[Required(ErrorMessageResourceName = "validazioneRichiesto", ErrorMessageResourceType = typeof(Resources.Resources))]
public string nome { get; set; }
那么,有什么合理的地方可以打电话吗?
我在控制器构造函数中初始化数据注释模型绑定器。
public CardController() : base() {
ModelBinders.Binders.DefaultBinder =
new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder();
}
因此,由于 Session 在控制器的构造函数中始终为 null,并且在数据注释验证字段之后调用操作重写, 我可以在哪里设置 CurrentCulture 和 CurrentUICulture 来获取本地化错误?
我尝试将 CurrentCulture 和 CurrentUiCulture 放入 Application_* (例如Application_AcquireRequestState 或 Application_PreRequestHandlerExecute)似乎没有效果......
解决方案
由于区域性是全局用户设置,因此我在 Global.asax.cs 文件的 Application_BeginRequest 方法中使用它。
它为我完成了工作(使用cookie),但会话也在那里可用。
编辑:
/布洛克·艾伦: http://www.velocityreviews.com/forums/t282576-aspnet-20-session-availability-in-globalasax.html/
会话在 PreRequesthandlerExecute 中可用。
问题在于,您的代码正在为服务器中执行,并且某些请求(例如Webresourxe.axd的一个请求)不会Utlilize session(因为处理程序未实现IrequiresessionState)。因此,将您的代码更改为仅在该请求有权访问会话时才访问会话。
更改您的代码来执行此操作:
protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
SetCulture();
}
无论如何,不确定它是否适用于 mvc
其他提示
仔细阅读您的问题后,我认为您的问题更多在于资源的编译方式。
签入 Resource.resx
属性,查找 Build Action
并将其设置为 Embedded Resource
也改变 Custom Tool
到 PublicResXFileCodeGenerator
替代文本http://img208.imageshack.us/img208/2126/captuream.png
我已经测试了一个迷你解决方案并且工作完美。如果您还有更多问题,我可以将示例发送给您。
您可以使用的另一种方法是将 lang 放入 URL 中,这样做有以下好处:
- 该网站被不同语言的搜索引擎抓取
- 用户可以用所选语言向朋友发送 URL
为此,请使用 Application_BeginRequest
中的方法 Global.asax
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim lang As String
If HttpContext.Current.Request.Path.Contains("/en/") Then
lang = "en"
Else
lang = "es"
End If
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang)
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang)
End Sub
看 这个问题 有关如何实施的更多信息
感谢 twk 接受的答案,OP 发布了最终解决方案如下:
void Application_PreRequestHandlerExecute(object sender, EventArgs e) {
if (Context.Handler is IRequiresSessionState ||
Context.Handler is IReadOnlySessionState) {
if (Session["lang"] == null) {
Session["lang"] = "it";
}
if (Request.QueryString["lang"] == "it" || Request.QueryString["lang"] == "en") {
Session["lang"] = Request.QueryString["lang"];
}
string lang1 = Session["lang"].ToString();
string lang2 = Session["lang"].ToString().ToUpper();
if (lang2 == "EN")
lang2 = "GB";
System.Threading.Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.CreateSpecificCulture(lang1 + "-" + lang2);
System.Threading.Thread.CurrentThread.CurrentUICulture =
System.Globalization.CultureInfo.CreateSpecificCulture(lang1 + "-" + lang2);
}
}