Передача исключения на страницу пользовательских ошибок с использованием IIS7 httpErrors - PullRequest
5 голосов
/ 15 декабря 2011

Я создал приложение ASP.NET MVC 3, используя httpErrors для обработки отображения сообщений об ошибках и тому подобного для пользователя. Этот код отлично работает и дублируется ниже.

<httpErrors existingResponse="Replace" defaultResponseMode="ExecuteURL" errorMode="Custom">
  <clear/>
  <error statusCode="403" path="/Error/Forbidden" responseMode="ExecuteURL"/>
  <error statusCode="404" subStatusCode="-1" path="/Error/NotFound" responseMode="ExecuteURL"/>
  <error statusCode="500" subStatusCode="-1" path="/Error/ServerError" responseMode="ExecuteURL"/>
</httpErrors>

Когда возникает исключение в контроллере, срабатывает BaseController.OnException (BaseController - это класс моего собственного создания). В этой функции я хочу сохранить исключение, чтобы мое действие ServerError могло посмотреть на его тип и сообщение, чтобы определить, что отображать пользователю. Весь метод скопирован ниже.

protected override void OnException(ExceptionContext filterContext)
{
    // doesn't work
    this.TempData["exception"] = filterContext.Exception;

    // doesn't work
    this.Session["exception"] = filterContext.Exception;

    // temporary hack
    ErrorController.RequestExceptions[this.Request.UserHostAddress] = filterContext.Exception;
    base.OnException(filterContext);
}

Когда запрос поступает к экземпляру ErrorController (ErrorController находится в другом пространстве имен, но я не думаю, что это актуально), по какой-то причине Server.GetLastError() возвращает ноль, TempData пуст, Session пуст, и Session.IsNewSession верно. Я попытался обойти эту проблему с помощью наличия в магазине приложений своего рода идентификатора запроса, но его, похоже, не существует, и сейчас лучшее решение, которое у меня есть, - это чрезвычайно хакерское «сохранить его, запросив IP, затем удалить это как только ErrorController подхватил его. "

Это (удивительно) работает, но должно быть более безопасное и более масштабируемое решение. Я не уверен, почему TempData очищается или почему сеанс перезапускается - это из-за ошибки, или это считается как два отдельных запроса? Независимо от того, есть ли обходной путь для получения желаемого поведения?

P.S. Я бы предпочел, если возможно, использовать запись httpErrors в web.config, а не код в Application_Error: это выглядит как более чистое, более декларативное решение.

P.P.S. Я нашел статью о проблемах с объектом Session во время перенаправлений ( link ), но там говорится, что проблема была исправлена. Большинство других вещей, с которыми я сталкивался, касалось более старой системы customErrors, но я буду продолжать искать.

1 Ответ

2 голосов
/ 15 декабря 2011

MVC имеет встроенную поддержку для обработки исключений и отображения пользовательского представления.По умолчанию MVC добавляет HandleErrorAttribute к методу RegisterGlobalFilters в файле Global.asax.cs.

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

Вам необходимо добавить представление с именем Error в папку Shared.Представление будет иметь модель типа HandleErrorInfo, которая в качестве свойства с именем Exception получает исключение

@model System.Web.Mvc.HandleErrorInfo

@Model.Exception.Message
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...