2013-04-17 4 views
16

मैं अनुरोध DTOs का स्वत: मान्यता से निपटने के लिए FluentValidation in ServiceStack का मूल्यांकन कर रहा हूँ:ServiceStack FluentValidation में कस्टम प्रतिक्रिया डीटीओ

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

त्रुटियाँ एक ErrorResponse डीटीओ serializing द्वारा ग्राहक को लौट रहे हैं और इस तरह लग रहे हो सकता है:

{ 
    "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." 
     } 
    ] 
} 

मैं जानना चाहता हूं कि एक अलग प्रतिक्रिया डीटीओ का उपयोग कर त्रुटियों को वापस करना संभव है या नहीं। उदाहरण के लिए:

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

मुझे पता है कि यह सेवा में स्पष्ट रूप से सत्यापनकर्ता उपयोग करना संभव है:

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

लेकिन सवाल यहाँ है कि क्या यह इस प्रमाणीकरण त्रुटि परोक्ष कहीं तो रोक दिया है करने के लिए संभव है कि मैं प्रतिक्रिया डीटीओ की जगह और एक क्लीनर सेवा कर सकते हैं:

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

अद्यतन:

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

एक कस्टम सत्यापन सुविधा लेखन द्वारा:

आगे स्रोत कोड में खुदाई के बाद, यह इस तरह ValidationFeature में जला दिया और अधिक विशेष रूप से अनुरोध फिल्टर है कि यह पंजीकृत करता है कि लग रहा है मैं वांछित प्रभाव प्राप्त करने में सक्षम था। लेकिन शायद एक और सुरुचिपूर्ण तरीका है?

उत्तर

13

मेरे पास सिर्फ checked in a Customization Error hook है जो आपको कस्टम त्रुटि फ़िल्टर निर्दिष्ट करने की अनुमति देता है ताकि सेवास्टैक (v3.9.44 +) के अगले संस्करण में इस उपयोग-मामले का समर्थन करना आसान हो सके।

CustomValidationErrorTests से आप अब ValidationFeature कॉन्फ़िगर कर सकते हैं एक कस्टम त्रुटि फिल्टर जो बजाय लौटा दी जाएगी, जैसे उपयोग करने के लिए:

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); 
} 
अब

अपने HTTP ग्राहक अपने अनुकूलित त्रुटि प्रतिसाद प्राप्त होगा:

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

चेतावनी: इस तरह से त्रुटि प्रतिक्रिया को अनुकूलित करते समय ServiceStack's typed C# clients अब टाइप अपवाद प्रदान नहीं करेगा क्योंकि वे त्रुटि प्रतिक्रिया को contai एन ResponseStatus डीटीओ संपत्ति।

+2

मैं क्या कह सकता हूं? अद्भुत! V3.9.44 + बिट्स तुरंत प्राप्त करना। –

संबंधित मुद्दे