В приложении asp.net mvc я успешно обрабатываю исключения, возникающие при выполнении вызова jquery $ .ajax из javascript в Controller. Я хочу обрабатывать ошибки таким же образом, когда я делаю javascript вызов fetch () из javascript, но я не могу понять, как распознать, что был сделан вызов fetch ().
Я использую класс, производный от HandleErrorAttribute, для обработки всех ошибок контроллера. Это делается добавлением следующей строки в global.asax Application_Start:
GlobalFilters.Filters.Add(new Areas.Insurance.Helpers.MyHandleErrorAttribute());
В MyHandleErrorAttribute я переопределяю метод OnException, чтобы я мог обрабатывать ошибки Ajax иначе, чем обычные ошибки get или post. Если есть ошибка ajax, я хочу вернуть объект, содержащий guid, и вызвать обратный вызов $ .ajax "error:" в javascript. Если есть ошибка, вызванная вызовом javascript fetch (), я хочу, чтобы response.ok возвращал «false» и возвращал объект, содержащий guid ошибки. Если ошибка не является ajax-ошибкой или ошибкой javascript fetch (), я хочу перенаправить на нашу страницу пользовательских ошибок. Код выглядит так:
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.Exception == null)
return;
//log the error
Guid guid = MyClass.LogError(filterContext.Exception.GetBaseException());
if (filterContext.HttpContext.Request.IsAjaxRequest()
&& filterContext.Exception != null)
{
//this is an error from a $ajax call.
//500 is needed so that $ajax "error:" function is hit, instead of "success:"
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult()
{
Data = new MyErrorObject()
{
Guid = guid
}
,JsonRequestBehavior = JsonRequestBehavior.AllowGet
//JsonRequestBehavior.AllowGet prevents following sporadic error: System.InvalidOperationException: This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
};
//this stops Application_OnError from firing
filterContext.ExceptionHandled = true;
//this stops the web site from using the default IIS 500 error.
//in addition must set existingResponse="Auto" ("PassThrough also works) in web.config httpErrors element.
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
else
{
//if condition to avoid error "Server cannot set status after HTTP headers have been sent"
if (!filterContext.HttpContext.Response.IsRequestBeingRedirected)
{
filterContext.Result = new RedirectToRouteResult(
new System.Web.Routing.RouteValueDictionary
{
{"action", "Error500" },
{"controller", "Error" },
{ "Guid", guid}
});
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
filterContext.ExceptionHandled = true;
}
}
}
Моя проблема в том, что когда вызов выполняется с использованием javascript fetch (), «IsAjaxRequest» возвращает false, поэтому первый блок «if» не ударил. Вместо этого я вхожу в блок «else», который устанавливает Http Response на «OK» и выполняет перенаправление на мою страницу ошибок, обе из которых не желательны (когда я получаю ошибку fetch (), я хочу вернуть 500 ответ, и, конечно, перенаправление не имеет никакого эффекта).
Как я могу узнать, что был выполнен вызов fetch () из javascript? Есть ли что-то похожее на IsAjaxRequest?
Вот как выглядит выборка JavaScript:
let url = '/myDomain/ThrowException';
fetch(url)
.then(function (data) {
if(data.ok){
//do something with data
}
else{
handleHttpErrorFunction(data);
}
})
.catch(function (error) {
handleFetchErrorFunction(error);
});
А вот (успешно обработанный) вызов jquery ajax, который я хочу заменить вызовом fetch ():
$.ajax({
url: '/myDomain/ThrowException',
type: 'GET',
success: function (data) {
//do something with data
},
error: function (XMLHttpRequest, ajaxOptions, ex) {
ajaxerrorhandler(XMLHttpRequest);
}