HttpPost 上的模型状态验证文化



>有谁知道您是否可以控制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;
    }
}

所以我的问题是,当我像这样使用模型状态验证时:

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 响应结果或仅通过调试 im 根据浏览器语言设置接收错误消息来访问错误时,这就是我想将其更改为当前处于活动状态

的语言的地方。

编辑

提前感谢,布斯汤姆森

我通过将更改区域性的代码从 Controller.OnActionExecute 移动到 Controller.ExecuteCore 来解决此问题

我处理过一个不完全相同但相似的情况。您应该能够将当前线程的 UICulture 设置为特定语言,并且事情应该可以正常工作。因此,请确定请求要针对哪个子域,并相应地设置区域性。 另请参阅: http://msdn.microsoft.com/en-us/library/system.threading.thread.currentuiculture.aspx

这个库应该有帮助 如何:为 ASP.NET 网页全球化设置区域性和 UI 区域性

将全球化节添加到 Web.config 文件

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

或以编程方式重写页面的 InitializeCulture 方法(Web窗体)

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

或者看看这个问题 在 ASP.Net MVC 应用中设置区域性

您可以在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);
}

最新更新