Returning 'other than HTML' formatted errors for AJAX calls to Web API

Investigating the Web API as part of an MVC 4 project as an alternative way to provide an AJAX-based API. I've extended AuthorizeAttribute for the MVC controllers such that, if an AJAX request is detected, a JSON-formatted error is returned. The Web API returns errors as HTML. Here's the AuthorizeAttribute that I'm using with the MVC controllers:

public class AuthorizeAttribute: System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);

        filterContext.Result = new RedirectToRouteResult(
            new RouteValueDictionary 
            {
                { "area", "" },
                { "controller", "Error" },
                { "action", ( filterContext.HttpContext.Request.IsAjaxRequest() ? "JsonHttp" : "Http" ) },
                { "id", "401" },
            });
    }
}

How could I reproduce this to provide equivalent functionality for the Web API?

I realize that I need to extend System.Web.Http.AuthorizeAttribute instead of System.Web.Mvc.AuthorizeAttribute but this uses an HttpActionContext rather than an AuthorizationContext and so I'm stuck by my limited knowledge of the Web API and the seemingly incomplete documentation on MSDN.

Am I even correct in thinking that this would be the correct approach?

Would appreciate any guidance.

Answers


To get the equivalent functionality in a Web API filter you can set the HttpActionContext.Response property to an instance of HttpResponseMessage that has the right redirect status code and location header:

protected override void HandleUnauthorizedRequest(HttpActionContext actionContext) {
    var response = new HttpResponseMessage(HttpStatusCode.Redirect);
    response.Headers.Location = new Uri("my new location");
    actionContext.Response = response;
}

I would very much go with Marcin's answer - at the end of the day, he has written the code!

All I would add is that as Marcin is saying, your best bet is to have a dedicated controller to return the errors as appropriate - rather than setting the response code 401 with JSON content in the attribute.

The main reason is that Web API does the content-negotiation for you and if you want to do it yourself (see if you need to serve JSON or HTML) you lose all that functionality.


Need Your Help

Bootstrap Font Awesome and IE8

internet-explorer-8 fonts twitter-bootstrap font-awesome

I'm using Font Awesome for my project and it works fine for chrome, firefox and IE9 but it fails show icons for ie8. I tried if it was my fault but also the project site doesn't show fonts ony my I...