2017-09-29 7 views
0

これを解決するのに手伝ってもらえますか? CustomAsyncをMustAsyncに変更しようとしていますが、動作させることができませんでした。以下は、継続トークンを渡していないように私は、あなたが以前のバージョン6にFluentValidationのバージョンを使用していると仮定しているので、私はバージョン5.6に私の答えをベースとしました、私のカスタムメソッドFluent ValidationをCustomAsyncからMustAsyncに変更する

RuleFor(o => o).MustAsync(o => { 
      return CheckIdNumberAlreadyExist(o) 
      }); 

     private static async Task<ValidationFailure> CheckIdNumberAlreadyExist(SaveProxyCommand command) 
     { 
      if (command.Id > 0) 
       return null; 

      using (IDbConnection connection = new SqlConnection(ConnectionSettings.LicensingConnectionString)) 
      { 
       var param = new DynamicParameters(); 
       param.Add("@idnumber", command.IdNumber); 

       var vehicle = await connection.QueryFirstOrDefaultAsync<dynamic>("new_checkDuplicateProxyIdNumber", param, commandType: CommandType.StoredProcedure); 

       return vehicle != null 
        ? new ValidationFailure("IdNumber", "Id Number Already Exist") 
        : null; 
      } 
     } 

答えて

0

です.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; 

    } 
} 

を、私は、コールが含まれていませんでしたあなたの問題の一部ではないので、データベースに追加してください。ここで注目すべき事柄がいくつかあります:

  1. FluentValidationは、あなたがに期待するとして、あなたは.WithName注釈方法を設定していないが、あなたは、あなたがこれをしなければならないオブジェクトの検証ルールを設定しているとき検証する特定のプロパティをデフォルトで指定します。オブジェクト全体を渡す場合は、エラーの報告方法を知らないだけです。
  2. 必須/ 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; 
    } 
} 

:この上の私のテイクはこのようなものになるだろうオブジェクト全体。

関連する問題