I'm currently working on a MVC4 application that needs to support 2 languages. I'm using DataAnnotations with resources in the form:
public class SignupModel
{
[Required(ErrorMessageResourceName = "Registration_ValidEmailRequired", ErrorMessageResourceType = typeof(Validation))]
[Email(ErrorMessageResourceName = "Registration_ValidEmailRequired", ErrorMessageResourceType = typeof(Validation))]
public string Email { get; set; }
[Required(ErrorMessageResourceName = "Registration_PasswordRequired", ErrorMessageResourceType = typeof(Validation))]
[StringLength(100, MinimumLength = 8, ErrorMessageResourceName = "Registration_PasswordInvalidLength", ErrorMessageResourceType = typeof(Validation))]
[DataType(DataType.Password)]
public string Password { get; set; }
}
I have created a global action filter that reads a language cookie if exists, and sets the current culture and uiculture accordingly. If the cookie doesn't exist it creates the cookie with the current culture. This is how the OnActionExecuting looks like in the filter:
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var langCookie = GetOrSetLanguageCookie(filterContext.HttpContext);
var culture = new CultureInfo(langCookie.Value);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
Everything works as expected except when this happens:
- Post from HTML form (let's say a fancy signup form in the home with no client side validation so nothing on its fancy layout is broken) to the Signup action in the Home controller.
- If the data posted have errors, they are displayed in the language matching the current culture. (nice and expected).
- Change the language, by using the drop down I enabled in the client which actually post back to the server. (I haven't implemented the PRG patter here yet, so I see the warning about the same data being re-posted).
- The view is rendered with the language I picked, however the validation messages remain in the same language they were initially.
If I debug the action filter handling the language switch, I can see the ModelState holding the errors in the original language, so my guess is validation only happens once in the server. I guess I need to clean the ModelState and force validation, but I was wondering if this is a hack and if there is a better way to deal with this issue.
Thanks! R.
Read Shaun Xu's post here: http://geekswithblogs.net/shaunxu/archive/2010/05/06/localization-in-asp.net-mvc-ndash-3-days-investigation-1-day.aspx
The ModelBinder (which is responsible on the obtaining of the validation messages) runs before the actions and before the actionfilters, and that's why your culture change happens before the validation message text is determined and is unaffected by it.
You can try to move this code to an earlier extension point, such as the controller's Execute or the ControllerFactory's CreateController method.
You can see my question here for a proposed solution: How to control the language in which model validation errors are displayed