我对 MVC 应用程序的本地化感到着迷。

我最近的一个问题 我遵循了这种方法:

  1. 语言存储在 Session["lang"] 中
  2. 每个控制器都继承自我自己的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 ToolPublicResXFileCodeGenerator

替代文本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);
  }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top