Обработка глобальных и HTTP-исключений с ASP.NET MVC - PullRequest
0 голосов
/ 26 сентября 2018

Я пытаюсь обработать глобальные (StatusCode 500) и http исключения в Asp.Net MVC, используя пользовательскую страницу ошибок с правильным HTTP-кодом состояния, используя событие Application_Error () в файле Global.asax.Для простоты на самом деле у меня только одна и та же ошибка представления для всех типов обработанных исключений.

Теперь проблема в том, что когда обрабатывается исключение 500, оно в первый раз попадает в раздел else в Application_Error, а затем возвращается в раздел if и, наконец, возвращает исключение http 404 вместо исключения 500.

Как я могу это исправить, прекратив запуск после того, как он переходит в раздел else Application_Error, когда обрабатывается исключение 500?

Это моя конфигурация: web.config

<system.web>
   <customErrors mode="Off"/>
</system.web>

 <system.webServer>
      <httpErrors errorMode="Custom" existingResponse="Replace">
        <remove statusCode="400"/>
        <remove statusCode="401"/>
        <remove statusCode="403"/>
        <remove statusCode="404"/>
        <remove statusCode="500"/>
        <error statusCode="400" responseMode="ExecuteURL" path="/Error"/>
        <error statusCode="401" responseMode="ExecuteURL" path="/Error"/>
        <error statusCode="403" responseMode="ExecuteURL" path="/Error"/>
        <error statusCode="404" responseMode="ExecuteURL" path="/Error"/>
        <error statusCode="500" responseMode="ExecuteURL" path="/Error"/>
      </httpErrors>
</system.webServer>

Метод Application_Error ():

public void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
        HttpException httpException = exception as HttpException;

        // Clear the response stream
        HttpContext httpContext = ((HttpApplication)sender).Context;
        httpContext.Response.Clear();
        httpContext.ClearError();

        var routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        routeData.Values.Add("action", "Error");
        routeData.Values.Add("exception", exception);


        if (exception.GetType() == typeof(HttpException)) //It's an Http Exception
        {
            routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());

            switch (routeData.Values["statusCode"])
            {
                case 400:
                    routeData.Values.Add("status", "400 - Bad Request");
                    break;
                case 401:
                    routeData.Values.Add("status", "401 - Access Denied");
                    break;
                case 403:
                    routeData.Values.Add("status", "403 - Forbidden");
                    break;
                case 404:
                    routeData.Values.Add("status", "404 - Page Not Found");
                    break;
                case 500:
                default:
                    routeData.Values.Add("status", "500 - Internal Server Error");
                    break;
            }
        }
        else
        {
            routeData.Values.Add("statusCode", 500);
            routeData.Values.Add("status", "500 - Internal Server Error");

        }

        // Avoid IIS7 getting in the middle
        httpContext.Response.TrySkipIisCustomErrors = true;

        // Call target Controller and pass the routeData.
        IController controller = new ErrorController();
        controller.Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
        Response.End();
        // clear error on server
        //Server.ClearError();
    }

Ошибка контроллера Контроллер:

public class ErrorController : Controller
    {
        // GET: /Error/
        public ActionResult Error(int statusCode, string status, Exception exception)
        {
            Response.StatusCode = statusCode;
            ViewBag.StatusCode = statusCode;
            ViewBag.Status = status;
            return View();
        }
    }

1 Ответ

0 голосов
/ 26 сентября 2018

Причина этого заключается в том, что тип Exception, выданный приложением, не всегда будет HttpException.Это может быть SQLException, SystemException, IndexOutOfRangeException и т. Д. И коды состояния всегда связаны только с HttpExceptions.Вот почему ваш код сначала входит в else часть, а затем в if часть.

Хотя он не должен приходить снова на if части, но если он приходит, то вы должны убедиться, что страница, на которую вы перенаправляете пользователя, больше не генерирует никаких других исключений.

Я бытакже рекомендуем удалить последний параметр из вашего кода, поскольку Exception является сложным типом, и мы обычно не передаем сложные типы в запросах Get.

Преобразование этого

public ActionResult Error(int statusCode, string status, Exception exception)

в

public ActionResult Error(int statusCode, string status)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...