2017-09-29 5 views
0

이 문제를 해결하는 데 도움을 줄 수 있습니까? CustomAsync를 MustAsync으로 변경하려고하지만 작동하도록 만들 수 없습니다. 다음은 내 사용자 지정 방법 나는 당신이 계속 토큰을 전달하지 않는 것처럼, 이전 버전 6 FluentValidation의 버전을 사용하고 있으리라 믿고있어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

, 그래서 버전 5.6에 내 대답을 기반으로 한 .2.

실제 규칙에 세미콜론이 누락되어 있으므로 예제 코드가 컴파일되지 않습니다. SaveProxyCommand 매개 변수에서 두 개의 다른 속성을 평가 중입니다.

나는 몇 가지 가정을 기반으로 매우 작은 POC 구축 한

:

을 감안할 때 2 개 클래스 :

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; 
    } 
} 

그리고 발리 :

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. 당신은 .WithName 주석 방법을 설정하지 않는,하지만 당신은 개체에 대한 유효성 검사 규칙을 설정하는 경우 FluentValidation가 당신을 예상대로,이 작업을 수행해야 유효성을 검사 할 특정 속성을 지정합니다. 전체 객체를 전달하는 경우 오류를 다시보고하는 방법을 알지 못합니다.
  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>(); 

을 위의 계좌 빈 컬렉션을 고려하지, 그것은 정의를 검색하기 위해 객체 그래프에 발굴하는 방법에 단지 예입니다 않습니다 상태.

전체 개체의 유효성을 검사하는 대신 속성마다 개별 규칙을 설정하면 유동성 검사가 가장 효과적입니다.

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; 
    } 
} 

이 더 많은 이야기처럼 읽을, 그것은 Id이 0 이하의 경우에만 규칙을 실행하는 .Unless 구조를 사용하고, 평가를 필요로하지 않습니다 이에 대한 필자의 의견은 다음과 같이 될 것이다 전체 개체.