ebvtrnog
ebvtrnog

Reputation: 4397

Making a generic-body method

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

Answers (1)

Aram
Aram

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

Related Questions