2011-02-25 66 views
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,并且对ModelState中包含对同一个MyForm实例的引用。但是,该表单未通过DataAnnotations或我的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)不验证表单时ModelState有到TryValidateModel(form)正确验证形式的实例的引用?

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

  3. 一般来说,为什么粘合剂负责更新ModelState

回答

1

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

ModelState属性只是一个包含模型当前状态的字典。查看模型状态就像一个错误列表。

如果您有自定义的ModelBinder,则可以将请求中的值映射到您选择的类中。这将最终成为你的行动方法的一个参数。

我不同意模型绑定器负责更新ModelState,因为ModelBinder在绑定这些值时运行,它在运行TryValidateModel之前仍然可以有IsValid = true。

当您稍后运行TryValidateModel(或针对此问题的ValidateModel)时,它将更新ModelState属性,并显示您拥有的任何错误。您还可以使用不同类型的验证方法(DataAnnotations,IValidatableObject ...)

+0

感谢您的回复。不过,我不同意你的一些观点。首先,'ModelBinder'不是必需的,以填充'ModelState'对象。但是,我的经验是,如果'ModelBinder'没有填充'ModelState'对象,那么绑定模型不会包含在验证中。如果有办法让请求上下文将绑定对象放入'ModelState'中,那么这可能是我题目问题的答案。 – arootbeer 2011-03-11 03:47:44

+0

我意识到'TryValidateModel'或'ValidateModel'会更新'ModelState'错误。我的观点是,MVC运行时似乎在我的自定义模型绑定器有机会将绑定模型放置在“ModelState”中之前调用这些方法(或类似的方法)**,这需要我明确地调用它们,感觉到我像一个不正确的操作顺序。我期望操作顺序是'接收请求 - >绑定参数到模型 - >验证模型 - >处理请求',但在这种情况下'验证模型'是'处理请求'的一部分。 – arootbeer 2011-03-11 03:54:06

相关问题