Reputation: 4397
I'm writing a Web Api. I am quite tired of always checking if a model is valid and always embracing a method with try
and catch
clauses. For that reason I wrote a method Try
that does just that. It works asynchronously.
Here is the code below that works:
[Route("account/[controller]")]
public class LoginController : Controller
{
private static async Task<Status> Try(ModelStateDictionary modelState, Func<Task<Status>> func)
{
try
{
return modelState.IsValid ? await func() : Status.InvalidFormat;
}
catch
{
return Status.InvalidFormat;
}
}
[HttpPost]
public async Task<Status> Login(AccountLoginModel model)
=> await Try(ModelState, async () =>
{
// yaaay! i'm safe! the model is valid!
// and if something bad happens, an exception will be caught!!
// now let's do something...
return await Task.FromResult(Status.OK);
});
}
My question is: is it possible to make this even shorter, simpler, clearer? I still don't really like this ugly large line:
public async Task<Status> Login(AccountLoginModel model)
=> await Try(ModelState, async () =>
What can I do to make this code better? Or is there any structure possible to implement that would make the job done?
EDIT
My version:
using Microsoft.AspNet.Mvc;
public class ValidateAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.ModelState.IsValid == false)
{
context.HttpContext.Response.StatusCode = 400;
context.Result = new JsonResult(/* my stuff */);
}
}
}
Upvotes: 1
Views: 60
Reputation: 5705
You can use a validation filter and register the filter to check for the model validation all the time like this:
public class ValidationFilter : ActionFilterAttribute
{
/// <summary>
/// Occurs before the action method is invoked.
/// </summary>
/// <param name="actionContext">The action context.</param>
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
actionContext.Response = actionContext
.Request
.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
}
And in your WebApiConfig Register method you should register your validation filter like this:
config.Filters.Add(validationFilter);
Upvotes: 1