2011-09-07 5 views
6

JSが無効なときにクライアントサイド検証とサーバーサイド検証で動作するMVC 3フレームワークで条件付きで必要なプロパティを作成するにはどうすればよいですか?例えば: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;} 
} 

この例のルールは、次のとおりLocationが設定されていない場合

  1. NameAgeが必要です。
  2. Locationは、NameAgeが設定されていない場合にのみ必要です。
  3. 名前、年齢、場所がすべて設定されていても問題ありません。

ビューでは、名前/年齢が設定されている場合、結果はActionに送信する必要があります。場所が設定されている場合は別のActionです。私は別のGet Urlを使って2つの別々のフォームを試しました。バリデーションルールが問題を引き起こしていることを除いて、これは素晴らしいことです。場所が提出されている場合PersonModelは名前と年齢があることを期待しているので、できれ、私は2つの別々のGETアクションの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に基づき、検証が失敗します同様に設定します。また、名前/年齢の場合も同様です。

上記のモックアップされた例では、JSが無効なときにクライアントサイド検証とサーバーサイド検証で動作するMVC 3フレームワークで条件付きで必要なプロパティをどのように作成しますか?

答えて

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)); 
    } 
} 

以下のような条件を表すreadonlyプロパティを作成できます。また、Ageプロパティをコードで "空"にすることはできません。サポートしたい場合は、そのプロパティにnullable 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;} 
} 
関連する問題