Skip to content

Instantly share code, notes, and snippets.

@ducas
Created February 27, 2012 02:55
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save ducas/1920999 to your computer and use it in GitHub Desktop.
Validating your model with Web API
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Data;
public class TodoApiController : ApiController
{
private BetterMobileSpaContext db = new BetterMobileSpaContext();
// GET /api/todoapi
public IEnumerable<TodoItem> Get()
{
return db.TodoItems.ToList();
}
// GET /api/todoapi/5
public TodoItem Get(int id)
{
return db.TodoItems.Find(id);
}
// POST /api/todoapi
[ValidateFilter]
public void Post(TodoItem value)
{
if (!ModelState.IsValid) return;
db.TodoItems.Add(value);
db.SaveChanges();
}
// PUT /api/todoapi/5
[ValidateFilter]
public void Put(int id, TodoItem value)
{
if (!ModelState.IsValid) return;
db.Entry(value).State = EntityState.Modified;
db.SaveChanges();
}
// DELETE /api/todoapi/5
public void Delete(int id)
{
TodoItem todoitem = db.TodoItems.Find(id);
db.TodoItems.Remove(todoitem);
db.SaveChanges();
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http.Filters;
using System.Net.Http;
public class ValidateFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var modelState = actionExecutedContext.ActionContext.ModelState;
if (!modelState.IsValid)
{
var errors = modelState
.Where(s => s.Value.Errors.Count > 0)
.Select(s => new KeyValuePair<string, string>(s.Key, s.Value.Errors.First().ErrorMessage))
.ToArray();
actionExecutedContext.Result = new HttpResponseMessage<KeyValuePair<string, string>[]>(errors, HttpStatusCode.BadRequest);
}
base.OnActionExecuted(actionExecutedContext);
}
}
@dkendrick
Copy link

Hey,

Thanks for sharing this code!

I have used your idea but used OnActionExecuting(HttpActionContext actionExecutingContext) rather than OnActionExecuted(HttpActionExecutedContext actionExecutedContext) as this allows me to remove the boilerplate if (!ModelState.IsValid) return from the methods.

@jfren484
Copy link

I took dkendrick's comment and further refined the attribute, so if anyone else comes here looking for a solution like I did, here's my take on it:

using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace VerifyPlatform.ClaimsTransformer.Presentation.Attributes.Filters
{
    public class ModelStateValidationAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (!actionContext.ModelState.IsValid)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
            }

            base.OnActionExecuting(actionContext);
        }
    }
}

@juanonsoftware
Copy link

Hi, thanks for your share!
If model is null (as I use Fiddler) the IsValid = true. Can we handle this case also within a filter scope?

@niisar
Copy link

niisar commented Apr 22, 2016

Yes we can handle If model is null

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

namespace TAMS.API.Infrastructure
{
    public class ValidateFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (!actionContext.ModelState.IsValid)
            {
                actionContext.Response = 
                    actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
            }else if(actionContext.ActionArguments.FirstOrDefault().Value == null)
            {
                actionContext.ModelState.AddModelError("Model Null", "Form is empty. Please enter some value");
                actionContext.Response =
                   actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
            }
            base.OnActionExecuting(actionContext);
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment