2014-06-18 37 views
1

我有這種多次使用的表單類'值','最大'字段只在某些情況下使用。如果'Show'屬性爲true並且顯示'Maximum'字段,我需要驗證'Maximum'是否有值。提前致謝!MVC5中的多重驗證要求

型號:

public class Value 
{ 
    public bool Show { get; set; } 
    public bool Required { get; set; } 
    [RequiredIf("Show", Domain.Comparison.IsEqualTo, true, ErrorMessageResourceType = typeof(Resources.ErrorMessages), ErrorMessageResourceName = "AuthorLabelIsRequired")] 
    public string Label { get; set; } 
    public string Description { get; set; } 
    [RequiredIf("Show", Domain.Comparison.IsEqualTo, true, ErrorMessageResourceType = typeof(Resources.ErrorMessages), ErrorMessageResourceName = "AuthorLabelIsRequired")] 
    public int? Maximum { get; set; } 
} 

HTML:

<tr> 
        <td>@Html.EnumString(Model.Data.DateSection.Key)</td> 
        <td>@Html.CheckBoxFor(m => m.Data.DateSection.Value.Show)</td> 
        <td>@Html.CheckBoxFor(m => m.Data.DateSection.Value.Required)</td> 
        <td> 
         @Html.TextBoxFor(m => m.Data.DateSection.Value.Label, new { @class = "form-control" }) 
         @Html.ValidationMessageFor(m => m.Data.DateSection.Value.Label) 
        </td> 
        <td>@Html.TextBoxFor(m => m.Data.DateSection.Value.Description, new { @class = "form-control" })</td> 
        <td></td> 
       </tr> 
       <tr> 
        <td>@Html.EnumString(Model.Data.DescriptionSection.Key)</td> 
        <td>@Html.CheckBoxFor(m => m.Data.DescriptionSection.Value.Show)</td> 
        <td>@Html.CheckBoxFor(m => m.Data.DescriptionSection.Value.Required)</td> 
        <td> 
         @Html.TextBoxFor(m => m.Data.DescriptionSection.Value.Label, new { @class = "form-control" }) 
         @Html.ValidationMessageFor(m => m.Data.DescriptionSection.Value.Label) 
        </td> 
        <td>@Html.TextBoxFor(m => m.Data.DescriptionSection.Value.Description, new { @class = "form-control" })</td> 
        <td> 
         @Html.TextBoxFor(m => m.Data.DescriptionSection.Value.Maximum, new { @class = "form-control" }) 
         @Html.ValidationMessageFor(m => m.Data.DescriptionSection.Value.Maximum) 
        </td> 
       </tr> 
+0

我的工作,解決此問題通過添加與''方法驗證布爾接口ICustomValidation'(ModelStateDictionary dict)'並添加一個在任何提供的'model'實例上調用'Validate'的預執行過濾器。每個模型中的Validate方法負責將條目移除(或添加)到ModelStateDictionary,最終確定模型是否有效。 – Dai

+0

使用@Dai描述的方法很容易解決(儘管我不知道是否需要定製預執行過濾器,也許在舊版本中有),但是您是否嘗試過任何一種方法? 「問題」被問到的方式使得它聽起來像你只是要求某人爲你寫代碼。 –

+0

嗯,我真的想知道是否有可能在上面的驗證聲明中有兩個條件。坦率地說,我是一個較新的程序員(2年),並不認爲答案會像戴made看起來那麼複雜。 –

回答

1

實際上,有處理條件驗證在ASP.NET MVC中一個相當完美的方式。你的模型最終會看起來像這樣:

public class Value : IValidatableObject { 
    public bool Show { get; set; } 
    public bool Required { get; set; } 
    [RequiredIf("Show", Domain.Comparison.IsEqualTo, true, ErrorMessageResourceType = typeof(Resources.ErrorMessages), ErrorMessageResourceName = "AuthorLabelIsRequired")] 
    public string Label { get; set; } 
    public string Description { get; set; } 
    [RequiredIf("Show", Domain.Comparison.IsEqualTo, true, ErrorMessageResourceType = typeof(Resources.ErrorMessages), ErrorMessageResourceName = "AuthorLabelIsRequired")] 
    public int? Maximum { get; set; } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { 
     if (this.Show && !this.Maximum.HasValue) { 
      yield return new ValidationResult("You must specify a maximum value"); 
     } 
    } 
} 

注意模型如何:

  1. 實現IValidateableObject
  2. 有一個名爲Validate方法,它返回類型IEnumerable<ValidationResult>

在模型綁定過程中這個方法會自動被調用,如果驗證結果返回你的ModelState將不再有效。因此,使用在你的控制器這個熟悉的代碼將確保除非您的自定義條件檢查出你不採取任何行動:

public class SomeController { 
    public ActionResult SomeAction() { 
     if (ModelState.IsValid) { 
      //Do your stuff! 
     } 
    } 
} 
+0

感謝賈斯汀的迴應,您的解決方案效果很好。我有一個問題,但我似乎無法找到驗證結果的字符串值存儲在哪裏。我需要在我的控制器中訪問它並將其設置爲錯誤消息。那可能嗎? –

+1

如果你想在你的視圖中顯示錯誤信息,你可以簡單地使用'@ Html.ValidationSummary()',它將吐出任何模型錯誤(如果有的話)。如果你確實需要訪問控制器端的錯誤消息,你可以使用:var allErrors = ModelState.Values.SelectMany(v => v.Errors);'獲得'ModelError'列表。然後你可以遍歷這些錯誤對象並查看'ErrorMessage'屬性來發揮你的魔力。 –

+0

你是上帝,謝謝! –