У меня есть приложение MVC 2, которое я хочу, чтобы все запросы возвращали json. Я переопределил HandleErrorAttribute
и AuthorizeAttribute
. Моя цель - чтобы все ошибки (даже 403 и 404) возвращались как json.
Вот мой обработчик ошибок. ExceptionModel
- это простой класс, определяющий любую ошибку, возвращенную моим приложением. Обработчик исключений - это класс, который переводит сведения об ошибке в форматированное электронное письмо и отправляет его мне.
public class HandleErrorJsonAttribute : System.Web.Mvc.HandleErrorAttribute
{
public override void OnException(ExceptionContext context)
{
context.ExceptionHandled = true;
RaiseErrorSignal(context.Exception);
context.RequestContext.HttpContext.Response.ContentType = "application/json";
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(context.HttpContext.Response.Output, new ExceptionModel(context.Exception));
}
private static void RaiseErrorSignal(Exception ex)
{
IExceptionHandler handler = Resolve();
handler.HandleError(ex.GetBaseException());
}
private static IExceptionHandler Resolve()
{
return ServiceLocator.Locate<IExceptionHandler>();
}
}
Вот модель исключения для уточнения
public class ExceptionModel
{
public int ErrorCode { get; set; }
public string Message { get; set; }
public ExceptionModel() : this(null)
{
}
public ExceptionModel(Exception exception)
{
ErrorCode = 500;
Message = "An unknown error ocurred";
if (exception != null)
{
if (exception is HttpException)
ErrorCode = ((HttpException)exception).GetHttpCode();
Message = exception.Message;
}
}
public ExceptionModel(int errorCode, string message)
{
ErrorCode = errorCode;
Message = message;
}
}
и, наконец, мой собственный атрибут авторизации. Я использую формы авторизации, но я не хотел никакого автоматического перенаправления. Я просто хочу, чтобы ошибка отображалась на экране и прекратила дальнейшую обработку.
public class AuthorizeTokenAttribute : System.Web.Mvc.AuthorizeAttribute
{
public bool SuperAdminOnly { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool authorized = base.AuthorizeCore(httpContext);
if(!SuperAdminOnly)
return authorized;
if(!authorized)
return authorized;
return SessionHelper.UserIsSuperAdmin(httpContext.User.Identity.Name);
}
protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
{
throw new HttpException(403, "Access Denied");
}
}
Все это прекрасно работает для большинства ошибок, но в нем отсутствует одна вещь. У меня есть действие контроллера, как это.
[AuthorizeToken]
[HttpPost]
public JsonResult MyAction()
{
return new JsonResult();
}
Работает нормально при отправке по почте, но при получении я получаю необработанную ошибку 404.
Ошибка сервера в приложении '/'.
Ресурс не найден.
Описание: HTTP 404. Ресурс
вы ищете (или один из его
зависимости) можно было бы удалить,
изменилось ли его имя, или
Временно недоступен. пожалуйста
просмотрите следующий URL и убедитесь, что
что написано правильно.
Запрошенный URL: / MyController / MyAction
Информация о версии: Microsoft .NET
Версия Framework: 4.0.30319; ASP.NET
Версия: 4.0.30319.1
Это происходит в GET, что следует ожидать в качестве поведения по умолчанию. Тем не менее, как я могу справиться с этим условием, чтобы я мог вместо этого вернуть json, как это
{"ErrorCode":404,"Message":"Page Not Found"}