从IValidatableObject.Validate返回的ValidationResult未本地化

时间:2011-08-29 12:36:32

标签: asp.net-mvc-3 localization ivalidatableobject

在我的ASP.NET MVC3站点中,我使用以下作为视图模型:

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

使用默认文化以外的任何文化查看网站时,Required验证邮件已正确本地化。但是,从Validate方法返回的消息始终位于默认文化中。

有没有办法正确本地化IValidatableObject.Validate消息?

2 个答案:

答案 0 :(得分:3)

似乎在文化可用于系统之前调用IValidatableObject.Validate方法。如果从控制器操作手动调用Validate方法,则错误消息已正确本地化。

使用列出here的方法的变体,我可以通过清除ModelState并强制在控制器操作中再次运行验证来获取视图中的本地化错误消息,如下所示:

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

答案 1 :(得分:2)

你在哪里设置文化?我在Controller&gt;中设置了它ExecuteCore,它按预期工作。

e.g。

 public class BaseController : Controller
    {
        protected override void ExecuteCore()
        {
            Thread.CurrentThread.CurrentUICulture = "en-GB"; 
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");

            base.ExecuteCore();
        }
  }