です.2。
実際のルールにセミコロンがないため、サンプルコードがコンパイルされません。また、SaveProxyCommand
パラメータで2つの異なるプロパティを評価しています。
私はいくつかの仮定に基づいて非常に小さいPOCを構築しました:
public class SaveProxyCommand {
public int Id { get; set; }
}
public class ValidationFailure {
public string PropertyName { get; }
public string Message { get; }
public ValidationFailure(string propertyName, string message){
Message = message;
PropertyName = propertyName;
}
}
そしてバリ:
は、2つのクラスを考えると
public class SaveProxyCommandValidator : AbstractValidator<SaveProxyCommand>{
public SaveProxyCommandValidator()
{
RuleFor(o => o).MustAsync(CheckIdNumberAlreadyExists)
.WithName("Id")
.WithState(o => new ValidationFailure(nameof(o.IdNumber), "Id Number Already Exist"));
}
private static async Task<bool> CheckIdNumberAlreadyExists(SaveProxyCommand command) {
if (command.Id > 0)
return true;
var existingIdNumbers = new[] {
1, 2, 3, 4
};
// This is a fudge, but you'd make your db call here
var isNewNumber = !(await Task.FromResult(existingIdNumbers.Contains(command.IdNumber)));
return isNewNumber;
}
}
を、私は、コールが含まれていませんでしたあなたの問題の一部ではないので、データベースに追加してください。ここで注目すべき事柄がいくつかあります:
- FluentValidationは、あなたがに期待するとして、あなたは
.WithName
注釈方法を設定していないが、あなたは、あなたがこれをしなければならないオブジェクトの検証ルールを設定しているとき検証する特定のプロパティをデフォルトで指定します。オブジェクト全体を渡す場合は、エラーの報告方法を知らないだけです。
- 必須/ MustAsyncは、カスタムオブジェクトの代わりに
bool
/Task<bool>
を返す必要があります。この問題を回避するには、検証に失敗したときに返されるカスタム状態を指定できます。あなたは、このような本へのアクセスを得ることができます
:上記
var sut = new SaveProxyCommand { Id = 0, IdNumber = 3 };
var validator = new SaveProxyCommandValidator();
var result = validator.ValidateAsync(sut).GetAwaiter().GetResult();
var ValidationFailures = result.Errors?.Select(s => s.CustomState).Cast<ValidationFailure>();
がは、アカウントに空のコレクションを取ることはありません、それは習慣を取得するために、オブジェクトグラフに掘るする方法のほんの一例です状態。
オブジェクト全体を検証するのではなく、プロパティごとに個別のルールを設定すると、最適化が最適に機能します。これは、より多くの物語のように、それはId
が0以下である、との評価を必要としない場合にのみ、ルールを実行するために.Unless
構文を使用して読ん
public class SaveProxyCommandValidator : AbstractValidator<SaveProxyCommand>{
public SaveProxyCommandValidator()
{
RuleFor(o => o.IdNumber).MustAsync(CheckIdNumberAlreadyExists)
.Unless(o => o.Id > 0)
.WithState(o => new ValidationFailure(nameof(o.IdNumber), "Id Number Already Exist"));
}
private static async Task<bool> CheckIdNumberAlreadyExists(int numberToEvaluate) {
var existingIdNumbers = new[] {
1, 2, 3, 4
};
// This is a fudge, but you'd make your db call here
var isNewNumber = !(await Task.FromResult(existingIdNumbers.Contains(numberToEvaluate)));
return isNewNumber;
}
}
:この上の私のテイクはこのようなものになるだろうオブジェクト全体。