2

我有一个复杂的对象,我正在绑定一个表单。模型绑定器如下所示:

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    var form = new MyForm();

    var myObject = ...; //try to load up the object

    /* logic to populate values on myObject */
    form.MyObject = myObject;

    bindingContext.ModelState.SetModelValue(bindingContext.ModelName, new ValueProviderResult(form, "", CultureInfo.CurrentUICulture));
    return form;
}

它正在做它应该做的事情;我从中得到了正确填充MyForm,并且对同一个 MyForm 实例的引用包含在 ModelState 中。但是,表单不会使用 theDataAnnotations或 my验证进行CustomValidation验证。为了进行验证,我必须TryValidateModel()在我的控制器中添加一个调用:

[HttpPost]
public ActionResult ProcessMyForm(MyForm form)
{
    //ModelState has the MyForm instance inside of it
    //TryValidateModel(ModelState); //this does not work
    TryValidateModel(form); //this works
    if (!ModelState.IsValid)
    {
        return View("Complete", form);
    }
    return RedirectToAction("Index");
}

这不仅会调用我的自定义验证,还会更新 ModelState.IsValid 的值。

除了我的标题问题,这提出了几个问题:

  1. 当引用正确验证的表单的同一实例时,为什么不TryValidateModel(ModelState)验证表单?ModelStateTryValidateModel(form)

  2. 为什么会TryValidateModel(form)导致 的值ModelState.IsValid被更新?

  3. 一般来说,为什么活页夹负责更新ModelState

4

1 回答 1

1

ModelBinder 的职责是将请求中的值绑定到您正在使用的模型中。

ModelState 属性只是一个包含模型当前状态的字典。将模型状态视为错误列表。

当您拥有自定义 ModelBinder 时,您可以将请求中的值映射到您选择的类中。这最终将作为您的操作方法的参数。

我不同意你认为 modelbinder 负责更新 ModelState,因为 ModelBinder 在绑定值时运行,它仍然可以在运行 TryValidateModel 之前具有 IsValid=true。

当您稍后运行 TryValidateModel(或 ValidateModel )时,它将使用您遇到的任何错误更新 ModelState 属性。您还可以使用不同类型的验证方法(DataAnnotations、IValidatableObject...)

于 2011-03-10T19:39:33.837 回答