ModelState Validation Culture on HttpPost

2019-07-03 16:11发布

问题:

Does anyone know if you can control the culture of the ModelState Object, im facing a problem in my multilingual application where the language is based on which subdomain from which you visit the site ex:

italia.domain.com - "Changes the culture to Italian"

german.domain.com - "Changes the culture to German"

The issue is that the language on the ModelState object when submitting a form seems to be controlled by the Clients browser and not the current threads culture.

So im searching for a solution where i can modify this behavior or override it so that the language on my italian subdomain always is italian and not the language of the clients browser.

EDIT

I already made the part where i change language based on subdomain:

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;
    }
}

So my problem is that when i use Modelstate validation like this:

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; }
}

And the check for modelstate validation part:

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);
      }
  }
}

When i then access the Errors through a Ajax Response result or just by debugging im receiving the error messages based on the browsers language setting, this is where i want to change it to be the language that is currently active instead.

EDIT

Thanks in advance, bsthomsen

回答1:

I solved this by moving the code where the culture is being changed from Controller.OnActionExecuting to Controller.ExecuteCore



回答2:

I have worked on a situation which was not exactly same but was similar. You should be able to set the UICulture of current thread to a specific language and things should work you expect it to. So, identify which subdomain the request is to and set the culture accordingly. See more: http://msdn.microsoft.com/en-us/library/system.threading.thread.currentuiculture.aspx



回答3:

This libk should help How to: Set the Culture and UI Culture for ASP.NET Web Page Globalization

add a globalization section to the Web.config file

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

or programmaticaly, override the InitializeCulture method for the page (WebForms)

protected override void InitializeCulture()
{

        UICulture = selectedLanguage ;
        Culture = selectedLanguage ;

        Thread.CurrentThread.CurrentCulture = 
            CultureInfo.CreateSpecificCulture(selectedLanguage);
        Thread.CurrentThread.CurrentUICulture = new 
            CultureInfo(selectedLanguage);

    base.InitializeCulture();
}

or look at this question Set Culture in an ASP.Net MVC app



回答4:

You can easily override the culture for each request in Global.asax.cs

In your case you could check the incoming URL and set the culture accordingly.

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);
}