2011-07-28 1 views
0

プロジェクトのビジネスルールを満たすためにカスタムバリデータを作成しています。MVC 3のヘルプを利用して、コレクションのプロパティでカスタムバリデータを作成することをお薦めします。

パブリッククラスCreateTestModel { 公共CreateTestModel() {

[Required] 
    public string Name { get; set; } 

    public string Description { get; set; } 

    public string BucketValidator { get; set; } 

    public RadioButtonListViewModel<GoalTypes> Goals { get; set; } 

    [EntityValidator(Property1:"IncludedEntities",Property2:"ExcludedEntities",MandatoryCount:1,isBucket=false, ErrorMessage = "One Entity is Compulsory")] 
    public IEnumerable<TestEntityModel> IncludedEntities { get; set; } 

    public IEnumerable<TestEntityModel> ExcludedEntities { get; set; } 


    public int MandatoryEntityCount { get; set; } 

    public IEnumerable<TestFilterModel> IncludedFilters { get; set; } 

    public IEnumerable<TestFilterModel> ExcludedFilters { get; set; } 
    [EntityValidator(Property1:"Buckets",Property2:"",MandatoryCount:2,isBucket=true,ErrorMessage = "Bucket is compulsory")] 

    [DisplayName("BucketErrors")] 

    public IEnumerable<BucketModel> Buckets { get; set; } 

    public bool AutoDecision { get; set; } 

    public DateTime StartDate { get; set; } 

    public DateTime EndDate { get; set; } 

    public int AdminId { get; set; } 

    [DefaultValue(true)] 
    public bool IsEnabled { get; set; } 
} 

私は私を満たすために使用されたエンティティのバリデータを作成し、上記のモデルに:今すぐ下記の

は、モデルでありますしかし、コレクションのプロパティで検証が行われるため、コレクションに複数の値がある場合、Validatorはエラーになりません。生成されたエラーをチェックインします。下記のように

EntityValidatorクラスがある:

[AttributeUsage(=真の継承、AttributeTargets.Property、AllowMultiple =偽)]

public class EntityValidator : ValidationAttribute,IClientValidatable 
{ 
    public int numberOfMandatoryEntities{get; private set;} 
    public int totalCountofIncludeEntities { get; private set; } 
    public bool isBucket { get; set; } 
    public string Property1{get; private set;} 
    public string Property2{ get; private set; } 
    private const string DefaultErrorMessageFormatString = "Atleast one entity is required"; 

    public EntityValidator(string Property1, string Property2, int MandatoryCount) 
    { 
     this.Property1 = Property1; 
     if (!String.IsNullOrEmpty(Property2)) 
      this.Property2 = Property2; 
     numberOfMandatoryEntities = MandatoryCount; 
    } 

    public EntityValidator(string Property1,string Property2,int MandatoryCount,bool isBucket) 
    { 
     this.Property1 = Property1; 
     if(!String.IsNullOrEmpty(Property2)) 
     this.Property2 = Property2; 
     this.isBucket = isBucket; 
     numberOfMandatoryEntities = MandatoryCount; 
    } 

    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(ErrorMessageString, name); 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     object property2Value = null; 
     object property1Value = null; 
     int property1Count=0; 
     int trafficCount = 0; 
     if(!String.IsNullOrEmpty(Property2)) 
     property2Value = validationContext.ObjectInstance.GetType().GetProperty(Property2).GetValue(validationContext.ObjectInstance, null); 
     property1Value = validationContext.ObjectInstance.GetType().GetProperty(Property1).GetValue(validationContext.ObjectInstance, null); 
     if (property1Value != null) 
     { 
     property1Count = ((IEnumerable<Object>)property1Value).Count(); 
      if (isBucket) 
      { 

       IEnumerable<BucketModel> bucket = ((IEnumerable<BucketModel>)property1Value); 

       var result = bucket.Select(x => x.TrafficPercentage); 
       foreach (var i in result) 
       { 
        trafficCount = trafficCount + i; 
       } 
      } 

     } 
     if(isBucket) 
     { 
      if(trafficCount<100) 
      { 
       var x = new ValidationResult(string.Format("Percentage total cannot be less than 100 %", validationContext.DisplayName)); 
       return x; 
      } 
     } 
     if (property2Value != null) 
     { 
      property1Count = property1Count +((IEnumerable<Object>)property2Value).Count(); 
     } 
     if (property1Count < numberOfMandatoryEntities) 
     { 
      return new ValidationResult(ErrorMessage); 
     } 

     return ValidationResult.Success; 
    } 
    #region IClientValidatable Members 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var x = new ModelClientValidationRule(); 
     x.ValidationType = "entityvalidator"; 
     x.ErrorMessage = string.Format(ErrorMessageString, metadata.GetDisplayName()); 
     x.ValidationParameters.Add("mandatoryentity", numberOfMandatoryEntities); 
     x.ValidationParameters.Add("checkforbucket", isBucket); 

     return new[] 
     { 
      x 
     }; 
    } 

今の問題は、次のとおり

1)場合コレクションに複数の値があり、IsValidがエラーを返しますが、ModelStateのどのプロパティにもバインドされていません。疑似プロパティを追加することはオプションですが、それより良い方法は何ですか?

2)このバリデータークライアント側は、ルールごとに擬似プロパティーを追加し、クライアントのvalidation規則で関数を指定し、アダプターを検証済みに追加することで簡単です。 しかし、このアプローチは非常に適切ではないようで、回避策があるようです。

助けてください!ありがとうございます。

答えて

0

あなたの場合のように検証規則が複雑になる場合は、データアノテーションを残してFluentValidation.NETに向かい、integration with ASP.NET MVCという大きな値を持つことをお勧めします(検証ルール複雑になる)。クライアントの検証ルールに関しては、ほとんどの一般的なルールをサポートしていますが、複雑になるとカスタムアダプターを書く方が優れています。

+0

ありがとうございます!私は私のプロジェクトでそれを使う前にそれを見ています。しかし、この種のバリデータのもう一つの問題は、デバッグ時に複数の値を持つコレクションを扱うとき、カスタムバリデータがIsValidをfalseとして返しますが、それぞれのプロパティにエラーをプラグインできないことです。今これをどうやって作業するのですか? – bhuvin

関連する問題