Так что я недавно построил в ExceptionFilter, который обрабатывает все ошибки, кроме Api Errors. ExceptionFilter выглядит следующим образом:Application_Error и 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 в нем) как так:
Server Error in '/' Application.
{"message":"validateMove validation failure:\r\nThe item is despatched and cannot be moved"}
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: SapphirePlus.Web.ApiException: {"message":"validateMove validation failure:\r\nThe item is despatched and cannot be moved"}
Source Error:
Line 181: if (response.StatusCode != HttpStatusCode.OK)
Line 182: throw new ApiException(result);
Так что мой вопрос, могу ли я получить Application_Error метод получить ошибки, которые AREApiException s и вернуть ошибку как JSON?
Похоже, вы забыли присвоить свой результат: 'filterContext.Result = result;' –
ах да, это не проблема, но, спасибо, что указали это! – r3plica