gpt4 book ai didi

.NET Web API : Class level validation attribute causes Web API to throw ArgumentNullException if instance is null

转载 作者:行者123 更新时间:2023-12-04 15:59:08 26 4
gpt4 key购买 nike

例如,我有一个 DTO 类,它看起来像这样:

public class ExampleDto
{
[DataMember(Name = "Date", IsRequired = true, Order = 1), Required]
public DateTime Date { get; set; }

[DataMember(Name = "ParentExample", IsRequired = false, Order = 2, EmitDefaultValue = false)]
public Guid? ParentExampleId { get; set; }
}

例如,如果用户提供了不正确的日期,例如:
<?xml version="1.0" encoding="UTF-8" ?>
<ExampleDto xmlns="http://customurl/">
<Date>2012-05-25T18:23:INCORRECTDATE</Date>
<ParentExample>B62F10A8-4998-4626-B5B0-4B9118E11BEC</ParentExample>
</ExampleDto>

或者只是一个空体,那么传递给 Action 的 ExampleDto 参数将为空(在前一种情况下,ModelState 将有错误)。

我对类应用了 CustomValidationAttribute,因此类声明如下所示:
[CustomValidation(typeof(CustomExampleValidator), "Validate")]
public class ExampleDto

现在我已经添加了这个,如果 ExampleDto 参数为空(因为一个空的主体,或者一个序列化问题),一个 ArgumentNullException 被抛出:
<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns="http://customurl" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Type>Failure</Type>
<Message>An unknown error has occurred</Message>
<Errors>
<Error>
<Message>System.ArgumentNullException</Message>
<MessageDetail>Value cannot be null. Parameter name:
instance</MessageDetail>
<StackTrace> at System.ComponentModel.DataAnnotations.ValidationContext..ctor(Object
instance, IServiceProvider serviceProvider,
IDictionary`2 items) at System.Web.Http.Validation.Validators.DataAnnotationsModelValidator.Validate(ModelMetadata
metadata, Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ShallowValidate(ModelMetadata
metadata, ValidationContext validationContext,
Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata
metadata, ValidationContext validationContext,
Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.Validate(Object
model, Type type, ModelMetadataProvider metadataProvider,
HttpActionContext actionContext, String keyPrefix)
at System.Web.Http.ModelBinding.FormatterParameterBinding.&lt;&gt;c__DisplayClass1.&lt;ExecuteBindingAsync&gt;b__0(Object
model) at System.Threading.Tasks.TaskHelpersExtensions.&lt;&gt;c__DisplayClass36`1.&lt;&gt;c__DisplayClass38.&lt;Then&gt;b__35()
at System.Threading.Tasks.TaskHelpersExtensions.&lt;&gt;c__DisplayClass49.&lt;ToAsyncVoidTask&gt;b__48()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1
func, CancellationToken cancellationToken)</StackTrace>
</Error>
</Errors>
</Response>

反射器显示在 ValidationContext 的构造函数中对对象执行空参数检查,就在执行 CustomValidationAttribute 之前。这看起来有点奇怪,因为空参数可以作为 Controller Action 的参数,不是吗?我认为此处的任何空参数检查都应该在用户代码中执行或由验证属性显式执行,而不是由框架执行。

如果用户提交正确的 XML/JSON,则不会抛出此异常,并且 CustomValidationAttribute 按预期执行,但不能总是信任用户提交正确的 XML/JSON,并且会因为他们的努力而得到一个看起来很钝的 ArgumentNullException,而不是一个我能够自己归还的。

我正在努力寻找其他经历过这种情况的人。有很多在属性级别应用“复合”验证器的例子,但对我来说在类级别应用验证更有意义(因为如果特定属性不为空,则需要多个属性,如果特定属性不为空,则需要其他属性)不同的属性不为空),我找不到任何可以说明在类级别应用的验证属性不受支持的内容。

最佳答案

我有同样的问题。不幸的是,有很多 ValidationAttributes。因此,在发布之前将它们全部重写为 IValidatableObject 并不真正可行。所以我的 又快又脏解决方案是在过滤器中捕获这些异常并发回正确的响应:

public class GeneralExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var exceptionType = context.Exception.GetType();
HttpResponseMessage response = null;

if(exceptionType == typeof(ArgumentNullException)
&& context.Exception.StackTrace.TrimStart().StartsWith("at System.ComponentModel.DataAnnotations.ValidationContext..ctor"))
{
response = new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent(context.Exception.Message)
};
}
else
{
response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(context.Exception.Message),
ReasonPhrase = "Unhandled exception"
};
}

context.Response = response;
_errorLogger.LogError(response?.ReasonPhrase, context.Exception);
}
}

并在 WebApiConfig.cs 中全局注册文件管理器:
config.Filters.Add(new GeneralExceptionFilterAttribute());

关于.NET Web API : Class level validation attribute causes Web API to throw ArgumentNullException if instance is null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17113608/

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