C# 覆盖验证程序中的http状态代码
我有以下DTO:C# 覆盖验证程序中的http状态代码,c#,servicestack,http-status-codes,fluentvalidation,C#,servicestack,Http Status Codes,Fluentvalidation,我有以下DTO: public class SomethingRequest { public string Code { get; set; } } code必须是唯一的,因此我创建了一个验证器,用于检查是否已经存在包含所提供代码的记录,如下所示 public class SomethingValidator: AbstractValidator<SomethingRequest> { public SomethingValidator(ISomethingR
public class SomethingRequest {
public string Code { get; set; }
}
code
必须是唯一的,因此我创建了一个验证器,用于检查是否已经存在包含所提供代码的记录,如下所示
public class SomethingValidator: AbstractValidator<SomethingRequest>
{
public SomethingValidator(ISomethingRepository repo) {
RuleFor(something => something.Code).Must(BeUnique);
}
private bool BeUnique(string code) { ... uniqueness check... }
}
公共类SomethingValidator:AbstractValidator
{
公共SomethingValidator(ISomethingRepository repo){
RuleFor(something=>something.Code).Must(BeUnique);
}
私有布尔BeUnique(字符串代码){…唯一性检查…}
}
当我使用验证功能时,验证器会自动连接到带有SomethingRequest
的所有方法,这真是太棒了
当条件失败时,我想返回409冲突
HTTP状态码,但400错误请求
总是返回
因此,问题是:
400 BadRequest
状态代码400 BADDREQUEST
状态代码,可以使用验证功能的ErrorResponseFilter
如下:
Plugins.Add(new ValidationFeature
{
ErrorResponseFilter = CustomValidationError
});
...
private object CustomValidationError(ValidationResult validationResult, object errorDto)
{
var firstError = validationResult.Errors.First();
return new HttpError(HttpStatusCode.Conflict, firstError.ErrorCode, firstError.ErrorMessage);
}
此筛选器看起来是用于全局解决方案的,因为它似乎没有为您提供任何确定错误来源的dto/服务的简单方法。我建议改为在1中进行更改
我是否滥用了验证功能?(即,自动连线验证器设计不用于应用程序逻辑检查)
我认为这最好在业务逻辑中完成,而不是在验证中,因为唯一性检查实际上是验证检查,而不是验证,因为它需要对数据源进行检查。解决了类似的问题
虽然您可以使用ErrorResponseFilter
覆盖验证错误的响应状态代码,但我建议您为此业务逻辑创建自己的请求过滤器,因为随着应用程序的增长,覆盖那里的响应将变得杂乱无章,而且这也不是真正的验证
在ServiceStack中使用筛选器属性非常简单:
公共类VerifySomethingCodeAttribute:Attribute,IHasRequestFilter
{
IHasRequestFilter IHasRequestFilter.Copy()
{
归还这个;
}
公共int优先级{get{return int.MinValue;}}
public void RequestFilter(IRequest请求、IResponse响应、对象requestDto)
{
SomethingRequest somethingRequestDto=作为SomethingRequest的requestDto;
if(somethingRequestDto==null)
返回;
//验证代码
//替换为合适的逻辑
//如果你需要这个数据库,你可以通过IoC连接它
//即HostContext.TryResolve();
bool isUnique=。。。
如果(!isUnique)
抛出HttpError.Conflict(“此记录已存在”);
}
}
然后简单地注释DTO:
[VerifySomethingCode]
公共类SomethingRequest{
公共字符串代码{get;set;}
}
然后,您可以确保DTO中的代码将被验证为唯一的,并且您可以返回所需的任何状态和响应。过滤器为您提供完全控制
希望这能有所帮助。谢谢您的链接。至于响应过滤器-这有点过分了,因为实际上,在提到的验证器中有更多的检查,而验证器并不打算抛出409。您是否能够将此检查添加到您将在服务期间执行的业务逻辑中?这样,您仍然可以使用dto在不同的方法中重复使用代码(假设在所有方法中都使用了一些业务逻辑)?非常感谢您的反馈,谢谢。:)@斯科特,还没有,我被卷入了其他的事情。我已经和我的同事们讨论过这个方法,我们认为这是一条路要走,但我们现在有400个还可以,还有一些更重要的事情要做。无论如何,我会让你知道:)没问题,对不起,我不是故意催你的。祝您的项目好运。@Scott别担心,不会造成任何伤害:)谢谢。@Scott我最终将验证移到了服务层。过滤方法可行,但不可行,因为每个请求需要一个过滤器,需要唯一性检查(或公共接口,或提取要验证的内容的其他方法)。