Возвращает форматированные ошибки, отличные от HTML, для вызовов AJAX к веб-API

Изучение веб-API в рамках проекта MVC 4 в качестве альтернативного способа предоставления API на основе AJAX. Я расширил AuthorizeAttribute для контроллеров MVC, чтобы при обнаружении запроса AJAX возвращалась ошибка в формате JSON. Веб-API возвращает ошибки в виде HTML. Вот AuthorizeAttribute, который я использую с контроллерами MVC:

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" },
            });
    }
}

Как я могу воспроизвести это, чтобы обеспечить эквивалентную функциональность для веб-API?

Я понимаю, что мне нужно расширить System.Web.Http.AuthorizeAttribute вместо System.Web.Mvc.AuthorizeAttribute, но здесь используется HttpActionContext, а не AuthorizationContext, и поэтому я застрял из-за своих ограниченных знаний о веб-API и, казалось бы, неполного документация в MSDN.

Я даже прав, думая, что это будет правильный подход?

Был бы признателен за любое руководство.


person DazWilkin    schedule 11.04.2012    source источник


Ответы (2)


Чтобы получить эквивалентную функциональность в фильтре веб-API, вы можете установить HttpActionContext.Response экземпляру HttpResponseMessage с правильным кодом состояния перенаправления и заголовком местоположения:

protected override void HandleUnauthorizedRequest(HttpActionContext actionContext) {
    var response = new HttpResponseMessage(HttpStatusCode.Redirect);
    response.Headers.Location = new Uri("my new location");
    actionContext.Response = response;
}
person marcind    schedule 11.04.2012
comment
+1. Я только что написал несколько строк в дополнение к вашему объяснению. Посчитал, что было бы грубо отредактировать ваш ответ. - person Aliostad; 12.04.2012
comment
@Aliostad, у тебя есть представитель SO, используй полномочия. Я бы не возражал (если это хорошая информация :) - person marcind; 12.04.2012
comment
Ваше здоровье. Я добавил еще один ответ с некоторыми пояснениями. - person Aliostad; 13.04.2012

Я бы очень согласился с ответом Марчина - в конце концов, он написал код!

Все, что я хотел бы добавить, это то, что, как говорит Марчин, лучше всего иметь выделенный контроллер для возврата ошибок по мере необходимости, а не устанавливать код ответа 401 с содержимым JSON в атрибуте.

Основная причина заключается в том, что Web API выполняет согласование контента за вас, и если вы хотите сделать это самостоятельно (посмотрите, нужно ли вам обслуживать JSON или HTML), вы потеряете все эти функции.

person Aliostad    schedule 11.04.2012