Asp.net mvc [handleerror] [авторизовать] с JsonResult?
Что является элегантным способом использования существующих атрибутов [HandleError] и [Authorize] при работе с вызовами XHR из javascript?
Итак, скажем, например, метод GetJson, который возвращает JsonResult.
При возникновении ошибки метод [HandleError] отправит обратно ViewResult, который будет восстановлен в функции обратного вызова в javascript.
Затем мне пришлось бы размещать собственный код везде в javascript для обработки и перенаправления любых сбоев и т.д.
То, что я хотел бы сделать, заключается в том, что атрибут [HandleError] возвращает JsonResult, если первоначальное действие планировало это сделать. Это может быть желаемое за действительное с моей стороны.
Аналогично, если приходит несанкционированный запрос Json, вместо того, чтобы возвращать новый HttpUnauthorizedResult, я хотел бы вернуть JsonResult, который позволяет моему коду на стороне клиента обрабатывать вещи обычным способом.
Я лаяю здесь неправильное дерево? Может быть, есть еще лучший способ, которым MVC может справиться с этим, о котором я не знаю?
Как другие люди справляются с этим сценарием?
Спасибо.
PS: Я понимаю, что могу создать свои собственные атрибуты [HandleJsonError] и [AuthorizeJson], которые возвращают JsonResults вместо ViewResults, но тогда мне придется ходить и помещать их на любой метод, который возвращает Json, и беспокоиться о Filter порядок и т.д. Конечно, было бы неплохо, если бы я мог использовать отражение или что-то, чтобы один и тот же атрибут действовал по-разному в зависимости от подписи исходного метода.
Ответы
Ответ 1
Нет. Прямо сейчас, они не помогают JSON. Однако:
Я понимаю, что могу создать свои собственные атрибуты [HandleJsonError] и [AuthorizeJson], которые возвращают JsonResults вместо ViewResults, но тогда мне придется ходить и помещать их на любой метод, который возвращает Json, и беспокоиться о порядке фильтра и т.д..
Что мы сделали, так это подтип существующих атрибутов и заставить их работать условно:
public sealed class AjaxAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.Result == null)
{
return;
}
else if (filterContext.Result.GetType() == typeof(HttpUnauthorizedResult)
&& filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new ContentResult();
filterContext.HttpContext.Response.StatusCode = 403;
}
}
}
Теперь JS-код может искать 403 (потому что ASP.NET ест 401 и возвращает страницу с ошибкой), и тот же атрибут работает для Ajax и не-Ajax. Поэтому проблем с фильтрами не возникает.