ASP.NET MVC:FluentValidationを使用した条件付きクライアント検証

私のタスクは、別のプロパティの値に応じてモデルプロパティの条件付き検証を行うことでした。 Googleは、そのようなタスクは非常に一般的だと言います。 それで、プロジェクトでそれをどのように解決したかを共有することにしました。



最も単純なオプションは、リフレクションを介して別のプロパティの値をチェックし、そのポイントがハットにある属性を記述することです。 しかし、この値は普遍的ではありませんでした。 確認するプロパティの名前を指定しても、別のプロパティのタイプはモデルごとに異なる場合があります。



かなりの時間をかけて美しいソリューションを探した後、FluentValidationライブラリに出会いました。 その魅力は、その助けを借りて、ほとんどすべての複雑さのモデルのチェックを簡単に設定でき、十分な機会がない場合は、独自のバリデータを作成し、それを目的のプロパティに簡単に割り当てることができることです。 プロジェクトのWebサイトには非常に優れたドキュメントがあります。 これがどのように機能するかの小さな例を次に示します。



[Validator(typeof(MyModelValidator))] public class MyModel { public string Name { get; set; } public string Description { get; set; } public bool IsDescriptionRequired { get; set; } } public class MyModelValidator: AbstractValidator<MyModel> { public MyModelValidator() { RuleFor(m => m.Name).NotEmpty(); RuleFor(m => m.Description).NotEmpty().When(m => m.IsDescriptionRequired); } }
      
      







塗りつぶし、最小長、最大長などの単純な条件の場合 クライアントでの検証は、すぐに実装されます。 より複雑なチェック(私の場合は条件付き)を実装するには、プロパティバリデータを実装し、IClientValidatableインターフェイスを実装する必要があります 。これについては、非常に多くの情報があります



基本的な考え方は、 jQuery.validateのデータセットを返すメソッドを実装することです



クライアントに検証を実装する必要がある場合、それぞれの場合に新しいクラスを実装する代わりに、ルールのセットを渡すことができるユニバーサルクライアントバリデータを作成したいと考えました。 次のような結果になりました。



 using GetClientValidationRulesFunc = Func<ModelMetadata, ControllerContext, IEnumerable<ModelClientValidationRule>>; class ClientValidator : PropertyValidator, IClientValidatable { private readonly GetClientValidationRulesFunc _getClientValidationRulesFunc; public ClientValidator(GetClientValidationRulesFunc getClientValidationRulesFunc) : base((string)null) { _getClientValidationRulesFunc = getClientValidationRulesFunc; } protected override bool IsValid(PropertyValidatorContext context) { // Suppress any server side validation return true; } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { return _getClientValidationRulesFunc(metadata, context); } }
      
      







そして、あなたはこのようなものでそれを使用することができます:



 public class MyModelValidator: AbstractValidator<MyModel> { public MyModelValidator() { RuleFor(m => m.Name).NotEmpty(); RuleFor(m => m.Description).NotEmpty().When(m => m.IsDescriptionRequired).SetValidator(new ClientValidator(GetValidationRules)); } public IEnumerable<ModelClientValidationRule> GetValidationRules(ModelMetadata metadata, ControllerContext context) { yield return new ModelClientValidationRule { ErrorMessage = "Description required", ValidationType = "validateDescription" }; } }
      
      







したがって、ライブラリの柔軟性を維持し、クライアント検証のルールを個別に設定できます。 また、クライアントが検証も実行するためには、独自の関数とそのためのアダプターを作成する必要があることも言う価値があります。



 $.validator.unobtrusive.adapters.addBool("validateDescription"); $.validator.addMethod("validateDescription", function (value, element, param) { if ( $("#IsDescriptionRequired").val() === "true" ) { return $.trim($("#Description").val()).length > 0; } return true; });
      
      







この記事は少しくしゃくしゃになっていてかなり乾燥していることがわかりましたが、1つの記事ですべての微妙な点を明らかにすることは非常に困難です。 おそらくこれは誰かに役立つでしょうが、必要がある場合は、興味のある詳細について詳しく説明できます。



NuGetを使用してパッケージをダウンロードできます:FluentValidation依存関係のあるFluentValidation.Mvc3



UPD:

global.asaxでモデルをバインドするときに検証を機能させるには、検証プロバイダーを登録する必要があります。



 protected void Application_Start(Object sender, EventArgs e) { FluentValidationModelValidatorProvider.Configure(); }
      
      







そして、バリデーターが作成されるクラスに、FluentValidation.Attributes名前空間にある属性を追加する必要があります。



 [FluentValidation.Attributes.Validator(typeof(MyModelValidator))] public class MyModel
      
      






All Articles