1. .NET Core 組み込みデータ検証の不十分さ
属性に検証ルール Attribute をマークするか、IValidatableObject インターフェイスを実装するか
このようにして、私たちの検証ルールはモデル クラスと結合されますが、これはオブジェクト指向の「単一責任原則」に違反します。
NET Core には十分な組み込み検証ルールがありません。一般的に使用される検証要件の多くでは、定義と検証ルールを記述する必要があります。
二.Fluent検証
上で、.NET Core の組み込みデータ検証メカニズムの不十分さについて述べました。ここでは、EF Core の Fluent API と同様の方法で検証ルールを構成できる、優れたデータ検証フレームワークである FluentValidation をお勧めします。つまり、モデル クラスの検証を別の検証クラス FluentValidation に入れることができます。これは、コンソール、WPF、ASPNET Core などのさまざまな NET オブジェクトで使用できます。
3. FluentValidationの基本的な使い方
ステップ 1、NuGet パッケージ FluentValidation.AspNetCore をプロジェクトにインストールします。
ステップ 2: 関連サービスを登録するためのコードを Program.cs に追加します。
1. bullder.Services.addfiuentValidation(fv =>{ |
2.アセンブリアセンブリ = Assembly.GetExecutingAssembly();
3. fv.RegiaterValidatorsFromAssenbly(アセンブリ);
4 });
RegisterValidatorsFromAssembly メソッドは、指定されたアセンブリの IValidator インターフェイスを実装するすべてのデータ検証クラスを依存関係注入コンテナーに登録するために使用されます。この例ではプロジェクトが 1 つだけであるため、すべてのデータ検証クラスもこのプロジェクトに書き込まれます。 Assembly.GetExecutingAssembly は、エントリ プロジェクトのアセンブリを取得します。実際のプロジェクトでは、データ検証クラスが複数のアセンブリに存在する場合があり、RegisterValidatorsFromAssemblies を呼び出して、登録するこれらのアセンブリを指定できます。
ステップ 3、モデル クラス Login2Request を作成します。
Login2Request クラス
パブリック レコード Login2Request(文字列 Email、文字列 Pansword、文字列 Paasmord2);
ここでの Login2Request クラスは単なる通常の C# クラスであり、インターフェイスを実装するようにマークされた Altribuk コンポーネントはなく、このクラスの唯一の役割はデータの転送であることがわかります。
ステップ 4、AbstractValidator から維持されるデータ検証クラスを作成する
Login2RequestValidator クラス
1 パブリック クラス Login2RequestValidator: AbatraceValidator<Login2Request>
2{
3public Login2RequestValidator()
4{
5RuleFor(x=>x.Email).NotNull().EmailAnddress()
6 .Must(v=>v.EndsWith("@ qq.com ") || v.EndsWith("@ 163.com "))
7. WithMessage("QQ および 163 メールボックスのみをサポートします");
8 RuleFor(x =>xPaseword),Hot0a11 1) .Lengtn(3, 10)
9 .WithMessage("パスワードの長さは 3 ~ 10 でなければなりません")
10 .Equal(x => x.Passwbrd2).withMessage("2 つのパスワードは同じである必要があります")
11 }
12 }
データ検証クラスは通常、AbstractValidator から継承します。AbstractValidator クラスはジェネリック クラスです。データ検証クラスがジェネリック パラメータを通じてどのクラスを検証するかを指定する必要があります。検証ルールは検証クラスの構築メソッドに記述されます。RuleFor を使用して、検証する属性を指定し、NotNull (空でない)、EmailAddress (電子メール アドレス)、Length (文字列の長さ) などの組み込みメソッドやその他の組み込みメソッドを使用して検証ルールを作成します。複数の検証ルールを呼び出すことができます。記述方法: 検証する必要がある各属性は一連の RuleFor 呼び出しに対応し、上記の 5 行目から 7 行目のコードは Emaii プロパティの検証に使用され、8 行目から 10 行目のコードは Emaii プロパティの検証に使用されます。パスワード属性を確認します。
FluentVabdation には豊富な検証ルールが組み込まれており、カスタム検証ルールを記述したい場合は、コードの 6 行目に示すように、Must メソッドに記述することができます。
FluentValidation の組み込み検証ルールにはデフォルトのエラー メッセージがあります。WithMessage メソッドを使用してエラー メッセージをカスタマイズすることもできます。WithMessage メソッドで設定されたエラー メッセージは、コードの 7 行目や 7 行目など、その前の検証ルールにのみ適用されます。コードの 10 行目を示します。
ステップ 5 では、Login2Request をパラメータとして受け取るアクション メソッドを作成します。次に、クライアント側でこの操作方法に対応するパスに不正なデータを送信し、サーバー側からの応答メッセージを図に示します。
FluentValidation を使用した後は、データ検証のルールを別個のデータ検証クラスに記述することができるため、モデル クラスとデータ検証クラスが「単一責任の原則」に従って独自の義務を実行できることがわかります。 FluentVialiciation カスタム検証コードの作成も簡単です。FlucntValidation と NET Core の組み込み検証メソッドは共存できます。つまり、検証ルールの一部を FluentVabdation で記述し、検証ルールの他の部分を :NET Core の組み込み検証メソッドで記述できますが、コードを統一するため、両方を混合しないことをお勧めします。
4. FluentValidation にサービスを挿入する
データ検証コードを記述するとき、依存関係注入コンテナーのサービスを呼び出す必要がある場合があります。FlucntValidation のデータ検証クラスは依存関係注入コンテナーを通じてインスタンス化されるため、構築メソッドを使用してデータ検証クラスにデータを追加することもできます。のサービス。
例
データベース内のテーブルには、システム内の既存のユーザー名、パスワード、その他の情報が記録されます。ユーザー テーブルのエンティティ クラスは User です。TestDbContext を通じてデータを読み取ります。
ログイン時にユーザー名が存在するかどうかを確認する検証クラスを実装してみましょう。
Login]Requcs クラスを定義します。このクラスには UserName (ユーザー名)、Passwond (パスワード) の 2 つの属性が含まれます
セックス。
次に、Login3Request を検証する別のクラスを作成します。
1パブリック クラス Login3RequestValidator:AbstractValidator<Login3Request >
2{
3publisLogin3RequestValidator(TestDbcontext dbCtx)
4{
5RuleFor(x => x.UserName).NotNull()
6 .Must(name=>dbCtx.User.Any(u=>u.UserName==name))
7.withMessage(c=>$"ユーザー名 {c.UserName} が存在しません");
8 }
9 }
ご覧のとおり、構築メソッドを通じて TestDbContext を挿入し、TestDbContext サービスを使用してコードの 6 行目の Must メソッドにユーザー名が存在するかどうかを確認しました。コードの 7 行目の withMessage メソッドでは、モデル クラスの属性をラムダ式の形式で使用してエラー メッセージをフォーマットすることもできることに注目してください。
通常、非同期コードはシステムのスループットを向上させることができるため、コード作成の原則は「非同期マザーを使用できる場合は、同期コードを使用しない」です。コードの 6 行目では、同期 Any メソッドを使用してユーザー名が存在するかどうかを判断します。EFCom には、Any メソッドの非同期バージョンである AnyAsync メソッドがあります。FluentValidation では、MustAsync と AnyAsync を使用して非同期検証ルールを作成できます。
非同期検証ルールのコード
5RuleFor(x => x.UserName).NotNull()
6 .MustAsync(name,_ )=>dbCtx.Users.AnyAsync(u=>u.UserName==name))
7.withMessage(c=>$"ユーザー名 {c.UserName} が存在しません");