2011-09-07 81 views
6

如何在MVC 3框架中使用客戶端驗證以及服務器端驗證來禁用JS時如何創建條件所需的屬性?例如:MVC 3有條件所需的屬性

public class PersonModel 
{ 
    [Required] // Requried if Location is not set 
    public string Name {get; set;} 
    [Range(1, 5)] // Requried if Location is not set 
    public int Age {get; set;} 

    [Required] // Only required if Name and Age are not set. 
    public string Location {get; set;} 
} 

在這個例子中的規則是:

  1. NameAge如果Location沒有設置是必需的。
  2. Location只有在未設置NameAge時才需要。
  3. 如果名稱,年齡和位置均已設置,則無關緊要。

在視圖中,如果設置了名稱/年齡,則需要將結果發送到Action。如果設置了位置,則會輸入另一個Action。我用兩個不同的Get Url的獨立表單進行了嘗試;除非驗證規則導致問題,否則這很有效。 Preferrably,我想使用2個獨立的獲取動作的URL,即

@model PersonModel 

@using(Html.BeginForm("Age", "Person", FormMethod.Post)) 
{ 
    @Html.TextBoxFor(x => x.Name) 
    @Html.ValidationMessageFor(x => x.Name) 
    @Html.TextBoxFor(x => x.Age) 
    @Html.ValidationMessageFor(x => x.Age) 
    <input type="submit" value="Submit by Age" /> 
} 

@using(Html.BeginForm("Location", "Person", FormMethod.Post)) 
{ 
    @Html.TextBoxFor(x => x.Location) 
    @Html.ValidationMessageFor(x => x.Location) 
    <input type="submit" value="Submit by Location" /> 
} 

基於上述PersonModel,如果該位置被提交,驗證將失敗,因爲PersonModel期待的姓名和年齡是也設置。反之亦然,名稱/年齡。

鑑於上面的模擬的例子,你如何創建條件所需的屬性與MVC 3框架,將與客戶端驗證以及服務器端驗證時,禁用JS?

回答

1

您可以將自定義驗證添加到您的模型,子類別ValidationAttribute或實施IValidatableObject

ValidationAttribute允許您通過實現IClientValidatable並通過jQuery註冊新的適配器和方法來相對簡單地添加客戶端驗證。 見Perform client side validation for custom attribute

IValidatableObject更適合於一次性驗證要求,其中重用不是一種選擇。它還導致代碼更簡單。不幸的是,使用這種方法沒有簡單的方法來實現客戶端驗證。

0

我創建了我自己的RequiredAttribute後代。它接受一個布爾屬性名稱,驗證的條件是什麼。請注意,此代碼不是生產準備好的,缺少錯誤檢查,並且可以在檢查null時進行一些改進。

[Localizable(false),AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 
public class RequiredIfAttribute : RequiredAttribute 
{ 
    public string BoolProperty { get; private set; } 
    public RequiredIfAttribute(string boolProperty) 
    { 
     BoolProperty = boolProperty; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     if (!Equals(value, null) || !string.IsNullOrEmpty(value as string)) 
      return ValidationResult.Success; 
     var boolProperty = validationContext.ObjectInstance.GetType().GetProperty(BoolProperty); 
     var boolValue = (bool)boolProperty.GetValue(validationContext.ObjectInstance, null); 
     if (!boolValue) 
      return ValidationResult.Success; 
     return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
    } 
} 

您可以創建一個只讀屬性來表示您的條件,如下所示。另請注意,您的代碼中Age屬性不能爲空。如果你想支持它,你應該爲該屬性使用一個可爲空的int(int?)類型。

public class PersonModel 
{ 
    // helper properties 
    public bool LocationNotSet { get { return string.IsNullOrEmpty(Location); } }  
    public bool NameAndAgeNotSet { get { return string.IsNullOrEmpty(Name) && Age <= 0; } } 

    [RequiredIf("LocationNotSet")] // Requried if Location is not set 
    public string Name {get; set;} 
    [Range(1, 5), RequiredIf("LocationNotSet")] // Requried if Location is not set 
    public int Age {get; set;} 

    [RequiredIf("NameAndAgeNotSet")] // Only required if Name and Age are not set. 
    public string Location {get; set;} 
}