2012-04-24 81 views
16

我想盡可能使用內置的驗證功能。我也想爲CRUD方法使用相同的模型。是否可以手動更新ModelState.IsValid?

但是,作爲下拉列表不能使用標準模式完成,我必須手動驗證它。在回發方法中,我想驗證下拉列表並將此結果添加到ModelState中,以便我不必驗證使用Data Annotation完成的所有其他參數。是否有可能實現這一目標?

我可能會誤解下拉列表,但從我讀的內容來看,下拉列表的Html對象名稱不能與模型中的屬性相同,以便正確設置所選值。此解決方法是否仍可以使用數據註釋?

謝謝。

回答

49

可以使用addModelError

ModelState.AddModelError(key,message) 

當您使用,它將無效的ModelState所以isValid將返回false。


更新
看到註釋@彼得的回答

如果你想從影響isValid()結果排除元素後,您可以在調用isValid()之前使用ModelState.Remove(field)方法。

+0

+1,用於提供鏈接addModelError – 2012-04-24 11:07:26

+10

ModelState.Remove(field)就是我所需要的!謝謝。 – 2012-04-24 12:55:32

+1

如果您在模型上使用IValidatableObject,請注意此問題,因爲此屬性驗證失敗時不會運行該驗證,但如果僅在您的Remove()屬性失敗時再次運行,則表明您的錯誤有效結果。 – pauloya 2012-11-26 16:23:46

5

您不能手動設置ModelState.IsValid屬性,但可以將消息添加到ModelState以確保IsValid爲false。

ModelState.AddModelError(); 
+0

這不是我正在尋找的。我正在尋找的是類似於相反的東西:ModelState.IgnoreModelError(「somekey」)忽略屬性的任何驗證錯誤,以somekey作爲關鍵字,以便ModelState.IsValid將繼續評估所有其他參數。我之所以需要這樣做,是因爲我試圖爲所有CRUD方法創建一個模型,但下拉列表問題要求我在「創建vs更新」中以不同的方式處理下拉列表。需要的數據註釋可以在創建而不是更新中使用。對於更新,我將不得不驗證它... – 2012-04-24 12:11:16

+0

手動,但我不希望其自動驗證錯誤導致整個模型無效。 – 2012-04-24 12:13:11

+0

當然,我可以通過使用更新的不同模型來解決問題。謝謝。 – 2012-04-24 12:14:32

11

另一種選擇是在模型中繼承IValidatableObject。實現其Validate方法,您可以保留所有其他驗證,並在此方法中編寫您想要的任何代碼。注意:您將返回一個空的IEnumerable<ValidationResult>以指示沒有錯誤。

public class Class1 : IValidatableObject 
{ 
    public int val1 { get; set; } 
    public int val2 { get; set; } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     var errors = new List<ValidationResult>(); 
     if (val1 < 0) 
     { 
      errors.Add(new ValidationResult("val1 can't be negative", new List<string> { "val2" })); 
     } 
     if (val2 < 0) 
     { 
      errors.Add(new ValidationResult("val2 can't be negative", new List<string> { "val2" })); 
     } 
     return errors; 
    } 
} 

編輯:在重新閱讀的問題後,我不認爲這適用於這種情況,但我離開這裏的答案的情況下,它可以幫助別人。

+0

謝謝。這是更復雜情況的一種選擇。感謝領先。 – 2012-04-24 12:56:28

+0

我個人比選擇的問題更喜歡這個選項。它保留了模型內部驗證模型的邏輯,而不是控制器。 – ohyeah 2016-09-26 11:27:15

2

是的,你可以做到這一點(也將用於CRUD方法同型號):

示例模型

public class User 
{ 
    public virtual int Id{ get; set; } 
    public virtual Role Role { get; set; } 
} 
public class Role 
{   
    [Required(ErrorMessage = "Id Required.")] 
    public virtual int Id { get; set; } 
    [Required(ErrorMessage = "Name Required.")] 
    public virtual string Name { get; set; } 
} 

示例視圖與驗證的下拉列表

@Html.DropDownListFor(m => m.Role.Id, (SelectList)ViewBag.gRoles, "-- Select --") 
@Html.ValidationMessageFor(m => m.Role.Id) 

控制器:清除所需的(但不是必需的)字段

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Creedit(User x) 
{ 
    x.Role = db.RoseSet.Find(x.Role.Id); 
    if (x.Role != null) 
    { 
     ModelState["Role.Name"].Errors.Clear(); 

    } 

    if (ModelState.IsValid) 
    { 
     // proceed 
    } 
    else 
    { 
     // return validation error 
    } 
} 
+1

非常感謝ModelState [「Role.Name」]。Errors.Clear() – InkHeart 2016-07-04 02:24:58

相關問題