Как распознать javascript fetch () в исключении HandleErrorAttribute OnException? - PullRequest
0 голосов
/ 07 марта 2019

В приложении 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);
        }

1 Ответ

0 голосов
/ 07 марта 2019

См. Ответ на связанный вопрос на С сервера, как был сделан вызов javascript fetch () (asp.net mvc) .Исправление заключается в отправке X-Requested-With XMLHttpRequest в заголовках:

fetch('/MyDomain/MyControllerAction', { headers: { 'X-Requested-With': 'XMLHttpRequest' } })
...