1. ホーム
  2. Web プログラミング
  3. ASP プログラミング
  4. アプリケーションのヒント

FluentValidationを使ったルール検証のためのNET Core

2022-01-18 18:09:42

言うまでもなく、ルールの検証は重要であり、無効なパラメータは、プログラムに例外を引き起こす可能性があります。

Web APIまたはMVCページを使用している場合、おそらく自己完結型のルール検証に慣れているため、私たちのコントローラはクリーンです:。

public class User
{
	[Required]
	public string FirstName { get; set; }
	
	[Required] public string LastName { get; set; }
	public string LastName { get; set; }
}

これはよくあることですが、今日はもっと良い選択肢を紹介したいと思います。FluentValidation は、オブジェクトの検証のための複雑なルールを流暢に定義できるようにすることで、検証ルールを簡単に構築し理解できるようにするライブラリで、これを ギズブ プロジェクトを探す

FluentValidationのインストール

.NET Coreで、ユーザー登録用のインターフェースを1つだけ用意し、Userクラスを入力として、Nugetにインストールしました。 FluentValidation .

最初のバリデーションを作成する

検証する各クラスには、それぞれ専用のバリデータを作成する必要があり、各バリデータ・クラスは AbstractValidator<T> ここで、Tは検証されるクラスであり、すべての検証ルールはコンストラクタで定義されます。

最も単純な検証は null 値に対するもので、 FirstName も LastName も null にしてはいけないと指定したい場合、このバリデーターは次のようになります。

public class UserValidator : AbstractValidator<User>
{
	public UserValidator()
	{
		RuleFor(x => x.FirstName).NotEmpty();
		RuleFor(x => x.LastName).NotEmpty();
	}
}

これで最初のバリデーターを作りました!超簡単でしょ?

他にも長さを検証するためのMinimumLength、MaximumLength、Lengthなどのルールがあり、このように1つのフィールドに複数のルールを割り当てることができます。

public class UserValidator : AbstractValidator<User>
{
	public UserValidator()
	{
		RuleFor(x => x.FirstName).NotEmpty();
		RuleFor(x => x.FirstName).MinimumLength(3);
    RuleFor(x => x.FirstName).MaximumLength(20);
		
		RuleFor(x => x.LastName).NotEmpty();
	}
}

エントリーの有効性確認

UserValidatorオブジェクトを生成してValidateメソッドを呼び出すと、バリデーションステータスとバリデーションを通過しなかったすべての情報を含むオブジェクトが返されます。

[HttpPost]
public IActionResult Register(User newUser)
{
	var validator = new UserValidator();
	var validationResult = validator.Validate(newUser);
	
	if (!validationResult.IsValid)
	{
		return BadRequest(validationResult.Errors.First().ErrorMessage);
	}

	return Ok();
}

プログラムを実行し、超長い名前を入力すると

{
  "FirstName": "Zhao Qian Sun Li Zhou Wu Zheng Wang Feng Chen Chu Wei Jiang Shen Han Zhu Qin You Xu He Lu Shi Zhang",
  "LastName": "Zhang"
}

バリデーションエラーが発生します: "「First Name」の長さは20文字以下でなければなりません。あなたは24文字を入力しました"。

このメッセージは気に入らないので、エラーメッセージをカスタマイズすることができます。これは簡単で、WithMessageメソッドを使うことができます。

- RuleFor(x => x.FirstName).MaximumLength(20);
+ RuleFor(x => x.FirstName).MaximumLength(20).WithMessage("Your name length has exceeded the limit! ");

流暢性検証

バリデーションルールをこのように変更することができます。

- RuleFor(x => x.FirstName).NotEmpty();
- RuleFor(x => x.FirstName).MinimumLength(3);
+ RuleFor(x => x.FirstName).NotEmpty().MinimumLength(3);

この検証ルールは、次のように他の属性にも適用することができます。

public UserValidator()
{
	RuleFor(x => x.FirstName)
		.MaximumLength(20).WithMessage("Your name length has exceeded the limit! ")
		.NotEmpty().MinimumLength(3);

	RuleFor(x => x.LastName).NotEmpty();
}

一般的なバリデーションルール

文字列については、EmailAddress、IsEnumName(値が指定されたEnum型で定義されているかどうかをチェックする)、InclusiveBetween(値が定義された範囲内にあるかどうかをチェックする)などのさまざまなメソッドを使用することができます。

さて、UserクラスにPasswordとConfirmPasswordという2つのフィールドを追加してみました。

Passwordフィールドは、5文字以上15文字以下の有効な文字列で、規則的なルールに適合している必要があります。セキュリティ・ルールに適合しているかどうかを定義するために、私はbool値を返すHasValidPasswordメソッドを定義しています。

private bool HasValidPassword(string pw)
{
	var lowercase = new Regex("[a-z]+");
	var uppercase = new Regex("[A-Z]+");
	var digit = new Regex("(\\d)+");
	var symbol = new Regex("(\\\W)+");

	return (lowercase.IsMatch(pw) && uppercase.IsMatch(pw) && digit.IsMatch(pw) && symbol.IsMatch(pw));
}

そして、パスワードバリデーションで使用します。

RuleFor(x => x.FirstName)
	.MaximumLength(20).WithMessage("Your name length has exceeded the limit! ")
	.NotEmpty().MinimumLength(3);

RuleFor(x => x.LastName).NotEmpty();

RuleFor(x => x.Password)
	.Length(5, 15)
	.Must(x => HasValidPassword(x));

また、次のように多少単純化することもできます。

RuleFor(x => x.Password)
			.Length(5, 15)
- .Must(x => HasValidPassword(x));
+ .Must(HasValidPassword);
	}

ConfirmPasswordフィールドの唯一の要件は、Passwordフィールドと同じであることです。

RuleFor(x => x.ConfirmPassword)
	.Equal(x => x.Password)
	.WithMessage("2 times the password doesn't match! ");

バリデータの注入

Startup クラスの ConfigureServices メソッドを以下のように変更します。

public void ConfigureServices(IServiceCollection services)
{
	services.AddControllers().AddFluentValidation();

	services.AddTransient<IValidator<User>, UserValidator>();
}

注:この場所のライフサイクルはTransientである。

こうすることで、登録インタフェースが呼び出されたときに、自動的にルールバリデーションが実行されるようになります:。

[HttpPost]
public IActionResult Register(User newUser)
{
	return Ok();
}

次に、パラメータを渡して再びインターフェースを呼び出そうとします。

{
  "FirstName": "Zhao Qian Sun Li Zhou Wu Zheng Wang Feng Chen Chu Wei Jiang Shen Han Zhu Qin You Xu He Lu Shi Zhang",
  "LastName": "Zhang"
}

明らかに、バリデーションは通過せず、インターフェイスは次のようなエラーメッセージを返します。

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "|c4523c02-4899b7f3df86a629.",
  "errors": { 
    "FirstName": [
      "Your name length has exceeded the limit! "
    ]
  }
}

より詳しい使い方は、公式ドキュメントをご覧ください。

元記事へのリンクです。 https://www.code4it.dev/blog/fluentvalidation

.NET Coreのルール検証は、過去の記事を検索していただくか、引き続き以下の記事をご覧ください。