我有一个ASP WebAPI项目,我想使用自定义的validateator属性在我的api中进行一些特殊的验证。为此,我在api中添加了一个过滤器(目前还没有什么特别的):
public class LogFilter : ActionFilterAttribute
{
public LogFilter()
{
}
public override void OnActionExecuting(HttpActionContext ActionContext)
{
Trace.WriteLine(string.Format("Action Method {0} executing at {1}", ActionContext.ActionDescriptor.ActionName, DateTime.Now.ToShortDateString()), "Web API Logs");
if (ActionContext.ModelState.IsValid == false)
{
ActionContext.Response = ActionContext.Request.CreateErrorResponse(
HttpStatusCode.BadRequest, ActionContext.ModelState);
}
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
Trace.WriteLine(string.Format("Action Method {0} executed at {1}", actionExecutedContext.ActionContext.ActionDescriptor.ActionName, DateTime.Now.ToShortDateString()), "Web API Logs");
}
}
下一步我要做的是创建一个新的ValidatorAttribute,称为GroupValidatorAttribute(目前尚无特殊实现,这只是一个演示我的问题的最小工作示例):
[AttributeUsage(AttributeTargets.Class)]
public class GroupValidatorAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null)
{
return new ValidationResult("" + validationContext.DisplayName + " cant be null");
}
return ValidationResult.Success;
}
}
因此,最后,我们需要使用GroupValidator属性的模型类:
[GroupValidator]
public class Student
{
public int? Age { get; set; }
public string name { get; set; }
}
肯定还有一个控制器,该控制器的端点类型为post,应从主体获取班级学生(我的模型)的对象:
[HttpPost]
[Route("Body")]
public HttpResponseMessage BodyTest(int id, [FromBody] Student student)
{
return Request.CreateResponse(HttpStatusCode.OK,
"Suc");
}
好的,到目前为止很好。它几乎达到了预期的效果,但是有一个案例使我发疯。如果我将一个空的正文发送(发布)到api中的终结点,则会发生System.ArgumentNullException。
这是完全例外:
“ ExceptionMessage”:“ Der Wert darn nic se NULL。\ r \ n参数名:instance”,“ ExceptionType”:“ System.ArgumentNullException”,“ StackTrace”:“ bei System.ComponentModel.DataAnnotations.ValidationContext..ctor(对象实例,IServiceProvider serviceProvider,IDictionary2 items)\r\n bei System.Web.Http.Validation.Validators.DataAnnotationsModelValidator.Validate(ModelMetadata metadata, Object container)\r\n bei System.Web.Http.Validation.DefaultBodyModelValidator.ShallowValidate(ModelMetadata metadata, BodyModelValidatorContext validationContext, Object container, IEnumerable
1验证程序)\ r \ n bei System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata元数据, BodyModelValidatorContextvalidationContext,对象容器,IEnumerable`1验证程序)\ r \ n在System.Web.Http.Validation.DefaultBodyModelValidator.Validate(对象模型,类型类型,ModelMetadataProvider元数据提供程序,HttpActionContext actionContext,字符串keyPrefix)\ r \ n北系统中。 Web.Http.ModelBinding.FormatterParameterBinding.d__18.MoveNext()\ r \ n --- Ende derStapelüberwachungvom vorhergehenden Ort,Des die Ausnahmeausgelöstwurde --- \ r \ n bei System.Runtime.Compilerucs.TaskAwaiter.ThrowForNonS (任务任务)\ r \ n是System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n是System.Web.Http.Controllers.HttpActionBinding.d__12.MoveNext()\ r \ n- -Ende derStapelüberwachungvom vorhergehenden Ort,一名来自澳大利亚的人--- \ r \ n在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \ n bei System.Runtime.CompilerServiceAnd.Noton (任务任务)\ r \ n System.Web.Http.Controllers.ActionFilterResult.d__5.MoveNext()\ r \ n --- Ende derStapelüberwachungvor vorhergehenden Ort,Dem die Ausnahmeausgelöstwurde --- \ r \ n bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \ n bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n bei System.Web.Http.Dispatcher.HttpControllerDispatcher.d__15。 MoveNext()“
在调试器中,我看到过滤器中的方法和验证器中的方法未命中。有人可以帮助我吗?
ArgumentNullException("instance")
异常是从ValidationContext
的构造函数生成的,因为在您的情况下instance
为null。
ValidationContext
的构造函数的代码片段:Source code
public ValidationContext(object instance, IServiceProvider serviceProvider,
IDictionary<object, object> items)
{
if (instance == null) {
throw new ArgumentNullException("instance");
}
....
现在,您的问题是:在调试器中,我可以看到我的过滤器和验证器中的方法未命中。
调用堆栈类似于
DataAnnotationsModelValidator.Validate() ->
DataAnnotations.ValidationAttribute.GetValidationResult() ->
GroupValidatorAttribute.IsValid()
ValidationContext
的构造函数是在Validate()
阶段创建的(引发null
异常),但是只有在已经执行IsValid()
检查之后才调用null
的实现。因此,IsValid()
永远不会打到您的案子。