Поэтому недавно я создал ExceptionFilter, который обрабатывает все ошибки, кроме ошибок API. ExceptionFilter выглядит следующим образом:
public class ExceptionAttribute : IExceptionFilter
{
/// <summary>
/// Handles any exception
/// </summary>
/// <param name="filterContext">The current context</param>
public void OnException(ExceptionContext filterContext)
{
// If our exception has been handled, exit the function
if (filterContext.ExceptionHandled)
return;
// If our exception is not an ApiException
if (!(filterContext.Exception is ApiException))
{
// Set our base status code
var statusCode = (int)HttpStatusCode.InternalServerError;
// If our exception is an http exception
if (filterContext.Exception is HttpException)
{
// Cast our exception as an HttpException
var exception = (HttpException)filterContext.Exception;
// Get our real status code
statusCode = exception.GetHttpCode();
}
// Set our context result
var result = CreateActionResult(filterContext, statusCode);
// Set our handled property to true
filterContext.ExceptionHandled = true;
}
}
/// <summary>
/// Creats an action result from the status code
/// </summary>
/// <param name="filterContext">The current context</param>
/// <param name="statusCode">The status code of the error</param>
/// <returns></returns>
protected virtual ActionResult CreateActionResult(ExceptionContext filterContext, int statusCode)
{
// Create our context
var context = new ControllerContext(filterContext.RequestContext, filterContext.Controller);
var statusCodeName = ((HttpStatusCode)statusCode).ToString();
// Create our route
var controller = (string)filterContext.RouteData.Values["controller"];
var action = (string)filterContext.RouteData.Values["action"];
var model = new HandleErrorInfo(filterContext.Exception, controller, action);
// Create our result
var view = SelectFirstView(context, string.Format("~/Views/Error/{0}.cshtml", statusCodeName), "~/Views/Error/Index.cshtml", statusCodeName);
var result = new ViewResult { ViewName = view, ViewData = new ViewDataDictionary<HandleErrorInfo>(model) };
// Return our result
return result;
}
/// <summary>
/// Gets the first view name that matches the supplied names
/// </summary>
/// <param name="context">The current context</param>
/// <param name="viewNames">A list of view names</param>
/// <returns></returns>
protected string SelectFirstView(ControllerContext context, params string[] viewNames)
{
return viewNames.First(view => ViewExists(context, view));
}
/// <summary>
/// Checks to see if a view exists
/// </summary>
/// <param name="context">The current context</param>
/// <param name="name">The name of the view to check</param>
/// <returns></returns>
protected bool ViewExists(ControllerContext context, string name)
{
var result = ViewEngines.Engines.FindView(context, name, null);
return result.View != null;
}
}
Как видите, если ошибка не является исключением ApiException, я перенаправляю пользователя на контроллер ошибок. ApiException — это просто ошибка, которая возникает, когда я делаю вызов API из MVC. Когда происходят эти ошибки, я хотел бы вернуть ошибку в виде JSON обратно клиенту, чтобы JavaScript мог ее обработать.
Я думал, что это не сделает обработка ошибки, но вместо этого она генерирует ошибку сервера (хотя и с ошибкой JSON) следующим образом:
Ошибка сервера в приложении '/'
{сообщение: сбой проверки validateMove:\r\nЭлемент отправлен и не может быть перемещен}
Описание: во время выполнения текущего веб-запроса возникло необработанное исключение. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.
Сведения об исключении: SapphirePlus.Web.ApiException: {сообщение: ошибка проверки validateMove:\r\nЭлемент отправлен и не может быть перемещен}
Ошибка источника:
Строка 181: если (response.StatusCode != HttpStatusCode.OK)
Строка 182: создать новое исключение ApiException (результат);
Итак, мой вопрос: могу ли я получить метод Application_Error для получения ошибок, которые ARE ApiException, и вернуть ошибку в формате JSON?
filterContext.Result = result;
- person Khanh TO   schedule 10.02.2016