【问题标题】:ModelState Validation Culture on HttpPostHttpPost 上的 ModelState 验证文化
【发布时间】:2012-08-07 17:26:52
【问题描述】:

有谁知道您是否可以控制 ModelState 对象的文化,我在我的多语言应用程序中面临一个问题,其中语言基于您访问站点的子域:

italia.domain.com - “将文化更改为意大利语”

german.domain.com - “将文化更改为德语”

问题在于提交表单时 ModelState 对象上的语言似乎由客户端浏览器控制,而不是当前线程文化。

所以我正在寻找一种解决方案,我可以在其中修改或覆盖它,以便我的意大利语子域上的语言始终是意大利语,而不是客户端浏览器的语言。

编辑

我已经完成了根据子域更改语言的部分:

var HttpHost = HttpContext.Request.ServerVariables["HTTP_HOST"];
var _hostname = (HttpHost.Split(':').Length > 1) ? HttpHost.Substring(0, HttpHost.IndexOf(':')) : HttpHost;

var allowedHostnames = "italiansubdomain.domain.com|it,frenchsubdomain.domain.com|fr,germansubdomain.domain.com|de,englishsubdomain.domain.com|en".Split(',');
foreach (var hostname in allowedHostnames)
{
    if (hostname.StartsWith(_hostname.ToLower()))
    {
        var lang = hostname.Split('|').Last();
        if (lang == "en") lang = "uk";
        // Updates the cultures for the dynamic language
        var ci = new CultureInfo(lang);
        System.Threading.Thread.CurrentThread.CurrentCulture = ci;
        System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
    }
}

所以我的问题是,当我像这样使用 Modelstate 验证时:

public class Email {
    [Required(ErrorMessageResourceName = "validation_required", ErrorMessageResourceType = typeof(Resources.Master)), StringLength(50, MinimumLength = 2, ErrorMessageResourceName = "validation_string_length_2_50", ErrorMessageResourceType = typeof(Resources.Master))]
    public string SenderName { get; set; }
    [Required(ErrorMessageResourceName = "validation_required", ErrorMessageResourceType = typeof(Resources.Master)), Email(ErrorMessageResourceName = "validation_email_invalid", ErrorMessageResourceType = typeof(Resources.Master))]
    public string SenderEmail { get; set; }
    [Required(ErrorMessageResourceName = "validation_required", ErrorMessageResourceType = typeof(Resources.Master)), StringLength(50, MinimumLength = 2, ErrorMessageResourceName = "validation_string_length_2_50", ErrorMessageResourceType = typeof(Resources.Master))]
    public string ReceiverName { get; set; }
    [Required(ErrorMessageResourceName = "validation_required", ErrorMessageResourceType = typeof(Resources.Master)), Email(ErrorMessageResourceName = "validation_email_invalid", ErrorMessageResourceType = typeof(Resources.Master))]
    public string ReceiverEmail { get; set; }
    public string Comment { get; set; }
}

以及检查模型状态验证部分:

if (!ModelState.IsValid) {
  var keys = ModelState.Keys.ToList();
  var values = ModelState.Values.ToList();

  for (var i = 0; i < keys.Count; i++)
  {
      var value = values[i];
      if (value.Errors.Count > 0)
      { 
          response.AddError(keys[i], value.Errors[0].ErrorMessage);
      }
  }
}

当我通过 Ajax 响应结果访问错误或仅通过调试我接收基于浏览器语言设置的错误消息时,我想将其更改为当前活动的语言。

编辑

提前致谢,bsthomsen

【问题讨论】:

    标签: c# asp.net asp.net-mvc-3


    【解决方案1】:

    我通过将更改文化的代码从 Controller.OnActionExecuting 移动到 Controller.ExecuteCore 解决了这个问题

    【讨论】:

    • 完美运行,谢谢。我发现关于这个问题的奇怪信息似乎如此稀缺。对于大多数人来说,这似乎只需要设置 UICulture 就可以正常工作,我想知道是什么让它表现得不同......
    • 好吧,解释很简单,因为 Controller.OnActionExecution 是控制器执行时发生的,并且发生在模型绑定之后,而模型绑定发生在控制器执行之前。
    • 在 asp.net mvc 4 中我建议重写 Controller 类的 Initialize 方法并使用本地化代码
    【解决方案2】:

    我曾处理过一个不完全相同但相似的情况。您应该能够将当前线程的 UICulture 设置为特定语言,并且事情应该可以按照您的期望进行。因此,确定请求的子域并相应地设置文化。查看更多:http://msdn.microsoft.com/en-us/library/system.threading.thread.currentuiculture.aspx

    【讨论】:

    • 感谢您的回复,我已经根据子域做出了更改的部分。但不知何故,ModelState 消息不会根据线程文化而改变,而是根据 HttpPosted 信息..
    【解决方案3】:

    这个 libk 应该可以帮助How to: Set the Culture and UI Culture for ASP.NET Web Page Globalization

    在 Web.config 文件中添加一个全球化部分

    <globalization uiCulture="es" culture="es-MX" />
    

    或以编程方式,覆盖页面 (WebForms) 的 InitializeCulture 方法

    protected override void InitializeCulture()
    {
    
            UICulture = selectedLanguage ;
            Culture = selectedLanguage ;
    
            Thread.CurrentThread.CurrentCulture = 
                CultureInfo.CreateSpecificCulture(selectedLanguage);
            Thread.CurrentThread.CurrentUICulture = new 
                CultureInfo(selectedLanguage);
    
        base.InitializeCulture();
    }
    

    或者看这个问题Set Culture in an ASP.Net MVC app

    【讨论】:

    • 感谢您的回复,我已经根据子域做出了更改的部分。但不知何故,ModelState 消息不会根据线程文化而改变,而是根据 HttpPosted 信息..
    【解决方案4】:

    您可以轻松覆盖Global.asax.cs 中每个请求的文化

    在您的情况下,您可以检查传入的 URL 并相应地设置文化。

    protected void Application_AcquireRequestState(object sender, EventArgs e)
    {
         //Create culture info object 
         CultureInfo ci = new CultureInfo("en");
    
         if(Request.Url.Host.Equals("italia.domain.com",
                                        StringComparison.InvariantCultureIgnoreCase))
         {
              ci = new CultureInfo("it");
         }
    
         System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
         System.Threading.Thread.CurrentThread.CurrentCulture =
                                          CultureInfo.CreateSpecificCulture(ci.Name);
    }
    

    【讨论】:

    • 感谢您的回复,我已经根据子域做出了更改的部分。但不知何故,ModelState 消息不会根据线程文化而改变,而是根据 HttpPosted 信息..
    猜你喜欢
    • 2012-03-09
    • 1970-01-01
    • 2013-02-21
    • 2019-08-29
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    相关资源
    最近更新 更多