gpt4 book ai didi

c# - ServiceStack FluentValidation 中的自定义响应 DTO

转载 作者:可可西里 更新时间:2023-11-01 03:10:12 26 4
gpt4 key购买 nike

我正在评估 FluentValidation in ServiceStack用于处理请求 DTO 的自动验证:

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

错误通过序列化 ErrorResponse DTO 返回给客户端,可能如下所示:

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

我想知道是否可以使用不同的响应 DTO 返回错误。例如:

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

但这里的问题是是否有可能在某处隐式拦截此验证错误,以便我可以替换响应 DTO 并获得更清洁的服务:

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

更新:

在进一步深入研究源代码后,它看起来像是ValidationFeature 中,更具体地说是它注册的请求过滤器:

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

通过编写自定义验证功能,我能够达到预期的效果。但也许有更优雅的方式?

最佳答案

我刚刚 checked in a Customization Error hook这允许您指定自定义错误过滤器,以便在下一版本的 ServiceStack (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将不再提供类型化异常,因为他们希望错误响应包含 ResponseStatus DTO 属性。

关于c# - ServiceStack FluentValidation 中的自定义响应 DTO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16054535/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com