2011-01-25 100 views
4

我有一个采取模型列表的操作。我想单独验证每个模型集合与整个模型集合。我试图使用TryValidateModel,但它似乎如果我的模型中的任何一个是无效的,所有这些都是无效的。我的表单显示5个SurveyResponseModels(一个包含两个必需字符串和两个整数的类)。如果我完全填写所有五个模型,我会得到下面的validCount = 5。但是,如果五个模型中的任何一个都不完整(因此验证失败),我会得到一个0的validCount。TryValidateModel的预期行为是什么?如果是这样,关于如何我可以一次验证这些的任何想法?在代码ASP.NET MVC3 TryValidateModel验证整个模型集合,而不仅仅是单个实例

[HttpPost] 
    public ActionResult Create(IList<SurveyResponseModel> respondents) 
    { 
     int validCount = 0; 

     foreach (SurveyResponseModel respondent in respondents) 
     { 
      if (TryValidateModel(respondent)) 
      { 
       validCount++; 
      } 
     } 
     ModelState.AddModelError("", validCount.ToString() + " respondents passed validation"); 
    } 

回答

4

来看,它在我看来,TryValidateModel将验证所提供的对象是给定类型的所有车型,而不仅仅是特定对象本身。此外,它还返回ModelState.IsValid属性的当前值,以便一旦有无效的模型,所有调用TryValidateModel将返回false。如果你想做这样的事情,我认为你需要为每个模型实例自己在那个特定的模型实例上获取并运行验证器。

我也认为模型验证器在您手动调用它们时已经运行。您可以通过在循环之前查看ModelState.IsValid的值来检查此(对于无效的模型)。如果它是假的,那么这意味着验证器是由模型绑定器运行的,这正是我想的事情。

您可以在http://aspnet.codeplex.com/找到MVC的源代码。

+0

他有一个好点。模型状态是一个单独的实例,它将保存每个交互的值。一旦出错,由于您选择的逻辑,所有这些都会失败。也许你应该尝试分别评估每个状态。您可以使用IValidatableObject来实现所需的行为 – 2012-08-21 02:24:09

1

我在另一篇文章中看到过这种行为。

要继续tvanfosson的建议,我建议你在foreach之前放一个断点,然后检查ModelState以查看错误是否已经存在。他们可能是:DefaultModelBinder已经把它们。然后我可以想到两种可能性:

  1. 错误被正确地传递,以某种方式标识每个被投诉人(我认为不是这种情况)。在这种情况下,一个简单的linq表达式可以为您提供有问题的受访者的不同数量。
  2. 错误是混合的,例如,如果2名受访者具有无效姓名,您只有一个姓名错误,或者您无法区分哪个答复者是关心的。在这种情况下,您需要创建自定义验证逻辑。您可以创建一个像RespondentListViewModel这样的对象并创建一个RespondentListViewModelBinder。您可以看到上面的源代码,以查看DefautlModelBinder如何验证列表并添加模型错误。

是的,这部分ASP.NET MVC的哪里是什么,我们希望它做的绑定逻辑没有做......

1

的源代码:

protected internal bool TryValidateModel(object model, string prefix) { 
     if (model == null) { 
      throw new ArgumentNullException("model"); 
     } 

     ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType()); 

     foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(metadata, ControllerContext).Validate(null)) { 
      ModelState.AddModelError(DefaultModelBinder.CreateSubPropertyName(prefix, validationResult.MemberName), validationResult.Message); 
     } 

     return ModelState.IsValid; 
    } 

它将如果出现错误,总会返回错误。

3

TryValidateModel()添加到验证错误列表中。使用ModelState.Clear()删除以前的错误。除非使用[ValidateInput(false)]属性,否则验证将自动作为模型绑定过程的一部分进行。有关更多信息,请参阅https://stackoverflow.com/a/8581918/1238406

相关问题