Required attribute on action parameter does not work
The code looks like this:
[HttpPost]
public ResultEntityVM Register([FromBody,Required] RegisterParam createAssessorParam)
{
if (ModelState.IsValid == false)
{
return null;
}
//other code
ResultEntityVM vm = new ResultEntityVM();
return vm;
}
When the parameter createAssessorParam
is equal null
, the value ModelState.IsValid
is true
. Why?
If I want to autodetect a parameter null
or not, what can I do? I can't just write the code:
if(RegisterParam != null)
{
//other
}
I ran into the same problem and solved it by executing the custom action attribute, evaluating all the action method parameter validation attributes.
I described the approach in this blog post where I am using ASP.NET Core 1.0, but the same approach should work with ASP.NET 4.
here is @MarkVincze's answer adjusted for the asp.net network
public class ValidateModelStateAttribute : System.Web.Http.Filters.ActionFilterAttribute
// there are two ActionFilterAttribute, one for MVC and another one for REST
{
/// <summary>
/// Called before the action method is invoked
/// </summary>
/// <param name="context"></param>
public override void OnActionExecuting(HttpActionContext context)
{
var parameters = context.ActionDescriptor.GetParameters();
foreach (var p in parameters)
{
if (context.ActionArguments.ContainsKey(p.ParameterName))
Validate(p, context.ActionArguments[p.ParameterName], context.ModelState);
}
if (!context.ModelState.IsValid)
{
context.Response = context.Request.CreateResponse(
HttpStatusCode.BadRequest,
context.ModelState.Select(_ => new { Parameter = _.Key, Errors = _.Value.Errors.Select(e => e.ErrorMessage ?? e.Exception.Message) }),
context.ControllerContext.Configuration.Formatters.JsonFormatter
);
}
}
private void Validate(HttpParameterDescriptor p, object argument, ModelStateDictionary modelState)
{
var attributes = p.GetCustomAttributes<ValidationAttribute>();
foreach (var attr in attributes)
{
if (!attr.IsValid(argument))
modelState.AddModelError(p.ParameterName, attr.FormatErrorMessage(p.ParameterName));
}
}
}
In WebAPI, the action parameter will never be zero. It is always created through the framework. Therefore, you prefer to use the attribute Required
on the properties of your view model if you want to make sure they are present.