ValidationResult Returned From IValidatableObject.Validate Is Not Localized
In my ASP.NET MVC3 si开发者_Python百科te, I am using the following as a View Model:
using DataResources = Namespace.For.The.Localization.Resources.IndexViewModel;
public class IndexViewModel, IValidatableObject {
private string _field1_check_value = "foo";
private string _field2_check_value = "bar";
[Required(ErrorMessageResourceName="Validation_Field1_Required", ErrorMessageResourceType=typeof(DataResources))]
[DataType(DataType.Text)]
public string Field1 { get; set; }
[Required(ErrorMessageResourceName="Validation_Field2_Required", ErrorMessageResourceType=typeof(DataResources))]
[DataType(DataType.Field2)]
public string Field2 { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (!(Field1.Equals(_field1_check_value) && Field2.Equals(_field2_check_value))) {
string[] memberNames = { "Field1", "Field2" };
yield return new ValidationResult(DataResources.Validation_InvalidCredentials, memberNames);
}
}
}
When the site is viewed using any culture other than the default, the Required
validation messages are properly localized. However, the message returned from the Validate
method are always in the default culture.
Is there a way to properly localize the IValidatableObject.Validate
messages?
It seems that the IValidatableObject.Validate
method is called before the culture is available to the system. If the Validate
method is called manually from the controller action, the error messages are properly localized.
Using a variation of the method listed here, I can get localized error messages into the view by clearing the ModelState and forcing the validation to be run again in the controller action as follows:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(IndexViewModel viewModel) {
if (ModelState.IsValid) {
//Do Stuff
return RedirectToAction("Action", "Controller");
}
else {
// The original validation did not properly localize error messages coming from IValidatableObject.Validate.
// Clearing the ModelState and forcing the validation at this point results in localized error messages.
ModelState.Clear();
var errors = viewModel.Validate(new ValidationContext(viewModel, null, null));
foreach (var error in errors)
foreach (var memberName in error.MemberNames)
ModelState.AddModelError(memberName, error.ErrorMessage);
}
return View("Index", viewModel);
}
Where are you setting the Culture? I set it in Controller > ExecuteCore and it works as expected.
e.g.
public class BaseController : Controller
{
protected override void ExecuteCore()
{
Thread.CurrentThread.CurrentUICulture = "en-GB";
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
base.ExecuteCore();
}
}
精彩评论