Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validation does not work if nothing is sent?

I annotated my model as this:

public class Instance
{
    [Required]
    public string Name { get; set; }
    public string Description { get; set; }
    [Required]
    public string DBServer { get; set; }
    [Required]
    public string Database { get; set; }
}

In the post method I get a null for the value if nothing was sent but Model.State is true. How can the state be true if nothing was sent? The next problem is that the CreateErrorResponse method throws an exception when I call it (probably because the value was null).

public HttpResponseMessage Post([FromBody]Instance value)
{
    if (value != null && ModelState.IsValid)
    {
        ...
    }
    else
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}

Edit: As it seems I didn't explain it right. I try now with some screenshots.

Case 1 I post a correct value using Fiddle and everything works as expected. ModelState.IsValid is true. Valid parameter

Case 2 I post a value with a missing required field (DBServer) and then again everything works as expected. ModelState.IsValid is false.

Missing required field

Case 3 My question. I send a post request with NO information and ModelState.IsValid is true. This seems very strange and I would like to know the reason. Thank you all for your answers.

enter image description here

like image 866
Raul Avatar asked Dec 27 '13 13:12

Raul


1 Answers

Try abstracting the ModelState check into a filter. You won't have to check for ModelState every time this way and if there's a problem

This code below comes from a great article on ModelState in WebAPI:

http://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api

using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Http.ModelBinding;

namespace MyApi.Filters
{
    public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(
                    HttpStatusCode.BadRequest, actionContext.ModelState);
            }
        }
    }
}

However, what you need to know is that ModelState only checks internal values, so you need to supply a check to see if the item is null before calling on ModelState.

Check this answer for more details: ModelState.IsValid even when it should not be?

like image 100
David East Avatar answered Oct 29 '22 17:10

David East