I got an asp webapi project and I want to use a custom validatorattribute to do some special validation in my api. For that purpose I added a filter into my api (nothing special currently):
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");
}
}
Next step I did is to create a new ValidatorAttribute called GroupValidatorAttribute (There is currently NO special implementation, it is just a minimal working example for demonstrating my problem):
[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;
}
}
So and finaly, we need a model-class using the GroupValidator attribute:
[GroupValidator]
public class Student
{
public int? Age { get; set; }
public string name { get; set; }
}
For sure there is also a controller, which has an endpoint with type post, which should get an object of class student (my model) from the body:
[HttpPost]
[Route("Body")]
public HttpResponseMessage BodyTest(int id, [FromBody] Student student)
{
return Request.CreateResponse(HttpStatusCode.OK,
"Suc");
}
Okay, so far so good. It nearly works as expected, but one case is driving me into madness. If I send (post) an empty body to my endpoint in the api, there occures an System.ArgumentNullException.
This is the full exception:
"ExceptionMessage": "Der Wert darf nicht NULL sein.\r\nParametername: instance",
"ExceptionType": "System.ArgumentNullException",
"StackTrace": " bei System.ComponentModel.DataAnnotations.ValidationContext..ctor(Object instance, 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, IEnumerable1 validators)\r\n bei System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, BodyModelValidatorContext validationContext, Object container, IEnumerable`1 validators)\r\n bei System.Web.Http.Validation.DefaultBodyModelValidator.Validate(Object model, Type type, ModelMetadataProvider metadataProvider, HttpActionContext actionContext, String keyPrefix)\r\n bei System.Web.Http.ModelBinding.FormatterParameterBinding.d__18.MoveNext()\r\n--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---\r\n bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n bei System.Web.Http.Controllers.HttpActionBinding.d__12.MoveNext()\r\n--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---\r\n bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n bei System.Web.Http.Controllers.ActionFilterResult.d__5.MoveNext()\r\n--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---\r\n bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n bei System.Web.Http.Dispatcher.HttpControllerDispatcher.d__15.MoveNext()"
In my debugger I can see that the methods in my filter and the methods in my validator are NOT hit. Is anybody who can help me?