Whilst this may concern to other topics as well, I'm just heading the following trouble with validation:
Model Annotation, Controller and Action
I use validation attributes from System.ComponentModel.DataAnnotations
. The model looks like
public class NewUserModel
{
[Required]
public string Username { get; set; }
}
So, nothing special. According to that, a pretty much default controller action
public ActionResult New()
{
return View(new NewUserModel());
}
and the view
@using (Html.BeginForm())
{
@Html.LabelFor(m => m.Username)
@Html.EditorFor(m => m.Username)
@Html.ValidationMessageFor(m => m.Username)
<button type="submit">save</button>
}
Setting Culture With Filter
Based on user preferences, culture is set via following filter
public class CultureFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
// simplified for this example
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("de");
}
}
which is registered in global.asax with
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CultureFilter());
}
Default language is english, so the web.config contains
<globalization culture="en-US" uiCulture="en"/>
With that done, client-side validation works perfectly. Data attributes for unobtrusive jQuery validation are localized as you can see in the resulting HTML:
<input data-val="true"
data-val-required="Das Feld Username ist erforderlich."
id="Username" name="Username" type="text" value="" />
The Problem: Server-side Validation Without Localization
The trouble is, that forcing server-side validation by disabling JavaScript renders following unlocalized validation message, while the data attribute is still localized:
<input data-val="true"
data-val-required="Das Feld Username ist erforderlich."
id="Username" name="Username" type="text" value="" />
<span class="field-validation-error" data-valmsg-for="Username"
data-valmsg-replace="true">The Username field is required.</span>
Looks pretty funny, doesn't it? ;-)
What Did I Try?
First, I checked if the server-side culture is set by web.config. Yes, it is. If I change the <globalization/>
attributes to german cultures (or just remove the node as by system language is german), the server-side validation message is german too.
This let me believe there might be a difference in times when server-side and client-side take their messages from resources. And maybe the server-side does it prior to executing the action, which means CultureFilter.OnActionExecuting()
is called after that, which of course is too late in this case.
So I tried to set the culture on begin request (global.asax):
protected void Application_BeginRequest()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("de");
}
Well, that did the trick. But I really think this is an ugly solution. So...
The Question: Am I Right and Do I Have Any Other Options?
Is it true, that server-side validation takes the messages from resource before a filter could set the culture? If not, what am I doing wrong? If yes, is there another, cleaner option for setting the culture than the global.asax "hack"?
Thank you in advance.
fr
for example, messages come in english, not french. So you may need to install some language packs. – Linus Caldwell