2013-04-17 15 views
16

:Özel tepki DTO ben istek DTOs otomatik doğrulama işlemek için <a href="https://github.com/ServiceStack/ServiceStack/wiki/Validation#fluentvalidation-for-request-dtos" rel="noreferrer">FluentValidation in ServiceStack</a> değerlendiriyorum

Plugins.Add(new ValidationFeature()); 
container.RegisterValidators(typeof(MyValidator).Assembly); 

Hatalar bir ErrorResponse DTO seri ile müşteriye iade edilir ve bu gibi görünebilir :

{ 
    "ErrorCode": "GreaterThan", 
    "Message": "'Age' must be greater than '0'.", 
    "Errors": [ 
     { 
      "ErrorCode": "GreaterThan", 
      "FieldName": "Age", 
      "Message": "'Age' must be greater than '0'." 
     }, 
     { 
      "ErrorCode": "NotEmpty", 
      "FieldName": "Company", 
      "Message": "'Company' should not be empty." 
     } 
    ] 
} 

Hataları farklı bir yanıt DTO kullanarak iade edip edemeyeceğinizi bilmek istiyorum. Örneğin:

{ 
    "code": "123", 
    "error": "'Age' must be greater than '0'." 
} 

Ben hizmetinde açıkça doğrulayıcı kullanmak mümkün olduğunu biliyoruz:

public MyService : Service 
{ 
    private readonly IValidator<MyRequestDto> validator; 
    public MyService(IValidator<MyRequestDto> validator) 
    { 
     this.validator = validator; 
    } 

    public object Get(MyRequestDto request) 
    { 
     var result = this.validator.Validate(request); 
     if (!result.IsValid) 
     { 
      throw new SomeCustomException(result); 
     } 

     ... at this stage request DTO validation has passed 
    } 
} 

Ama burada soru, bu doğrulama hatası yere kadar örtülü olarak ele sahip olmak mümkün olup olmadığıdır ben tepki DTO değiştirip daha temiz bir hizmet olabilir:

public MyService : Service 
{ 
    public object Get(MyRequestDto request) 
    { 
     ... at this stage request DTO validation has passed 
    } 
} 

GÜNCELLEME:

public class ValidationFilters 
{ 
    public void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto) 
    { 
     var validator = ValidatorCache.GetValidator(req, requestDto.GetType()); 
     if (validator == null) return; 

     var validatorWithHttpRequest = validator as IRequiresHttpRequest; 
     if (validatorWithHttpRequest != null) 
      validatorWithHttpRequest.HttpRequest = req; 

     var ruleSet = req.HttpMethod; 
     var validationResult = validator.Validate(
     new ValidationContext(requestDto, null, new MultiRuleSetValidatorSelector(ruleSet))); 

     if (validationResult.IsValid) return; 

     var errorResponse = DtoUtils.CreateErrorResponse(
      requestDto, validationResult.ToErrorResult()); 

     res.WriteToResponse(req, errorResponse); 
    } 
} 

özel doğrulama özelliğini yazarak:

ayrıca kaynak koduna kazma sonra, bu ValidationFeature içine yanmış ve kaydeder daha spesifik istek filtresi olduğunu benziyor İstenen etkiyi başardım. Ama belki daha zarif bir yol var mı?

cevap

13

ServiceStack'ın sonraki sürümünde (v3.9.44 +) bu kullanımı desteklemeyi kolaylaştırmak için özel bir hata filtresi belirtebilmeniz için yalnızca checked in a Customization Error hook kullanıyorum. CustomValidationErrorTests itibaren

artık yerine iade edilecektir özel bir hata filtresi, örneğin kullanmak üzere ValidationFeature yapılandırabilirsiniz:

Şimdi
public override void Configure(Container container) 
{ 
    Plugins.Add(new ValidationFeature { 
     ErrorResponseFilter = CustomValidationError }); 
    container.RegisterValidators(typeof(MyValidator).Assembly);   
} 

public static object CustomValidationError(
    ValidationResult validationResult, object errorDto) 
{ 
    var firstError = validationResult.Errors[0]; 
    var dto = new MyCustomErrorDto { 
     code = firstError.ErrorCode, error = firstError.ErrorMessage }; 

    //Ensure HTTP Clients recognize this as an HTTP Error 
    return new HttpError(dto, HttpStatusCode.BadRequest, dto.code, dto.error); 
} 

özelleştirilmiş hata yanıtı alacaktır HTTP Müşteriler:

try 
{ 
    var response = "http://example.org/customerror".GetJsonFromUrl(); 
} 
catch (Exception ex) 
{ 
    ex.GetResponseBody().Print(); 
    //{"code":"GreaterThan","error":"'Age' must be greater than '0'."} 
} 

Uyarı: Hata Yanıtını bu şekilde özelleştirirken ServiceStack's typed C# clients artık Hata Yanıtının beklendiği gibi yazılan istisnalar sağlamayacaktır. n a ResponseStatus DTO özelliği.

+2

Ne söyleyebilirim? Muhteşem! V3.9.44 + bitleri hemen almak. –