2011-01-25 196 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

相關問題