3

我对 MVC 应用程序的本地化感到疯狂。

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

  1. 语言存储在 Session["lang"]
  2. 每个控制器都继承自我自己的BaseController,它覆盖了OnActionExecuting,并在这个方法中读取Session并设置CurrentCulture和CurrentUICulture

这很好用,直到数据注释层出现。似乎它在动作本身执行之前被调用,因此它总是以默认语言获取错误消息!

字段声明如下所示:

[Required(ErrorMessageResourceName = "validazioneRichiesto", ErrorMessageResourceType = typeof(Resources.Resources))]
public string nome { get; set; }

那么,有什么合理的地方可以拨打电话吗?

我在 Controller 构造函数中初始化了 Data Annotation Model Binder。

public CardController() : base() {
    ModelBinders.Binders.DefaultBinder =
    new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder();
}

因此,由于 Session 在控制器的构造函数中始终为空,并且在数据注释验证字段之后调用操作覆盖,我可以在哪里设置 CurrentCulture 和 CurrentUICulture 以获取本地化错误?

我尝试将 CurrentCulture 和 CurrentUiCulture 放入 Application_*(例如 Application_AcquireRequestState 或 Application_PreRequestHandlerExecute)似乎没有任何效果......

4

4 回答 4

2

由于文化是一个全局用户设置,我在 Application_BeginRequest 方法的 global.asax.cs 文件中使用它。

它为我工作(使用 cookie),但 Session 也在那里可用。

编辑:

/由布洛克艾伦: http ://www.velocityreviews.com/forums/t282576-aspnet-20-session-availability-in-globalasax.html/

会话在 PreRequesthandlerExecute 中可用。

问题是您的代码正在针对服务器的每个请求执行,并且某些请求(如 WebResourxe.axd 的请求)不使用 Session(因为处理程序没有实现 IRequireSessionState)。因此,如果该请求可以访问它,请将您的代码更改为仅访问 Session 。

更改您的代码以执行此操作:

protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
    if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
        SetCulture();    
}

无论如何,不​​确定它是否适用于 mvc

于 2009-10-02T11:26:58.470 回答
1

仔细阅读您的问题后,我认为您的问题更多地在于资源的编译方式。

检查Resource.resx属性,找到Build Action并将其设置为Embedded Resource 也更改Custom ToolPublicResXFileCodeGenerator

替代文字 http://img208.imageshack.us/img208/2126/captuream.png

我已经测试了一个迷你解决方案并且效果很好。如果您有更多问题,我可以将示例发送给您。

于 2009-10-06T15:08:39.763 回答
0

您可以使用的另一种方法是将 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

有关如何实施它的更多信息,请参阅此问题

于 2009-10-02T21:53:06.803 回答
0

感谢 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);
  }
}
于 2015-02-09T14:30:10.077 回答