Моя цель - создать обработку ошибок в приложении, которая обрабатывает все управляемые ошибки, а не только связанные с MVC. Поэтому я не использую шаблон HandleErrorAttribute, потому что он предназначен только для ошибок MVC, а не для других управляемых ошибок.
В моем Global.asax у меня есть:
protected void Application_Error()
{
string displayError = ConfigurationManager.AppSettings["DisplayError"];
NameValueCollection serverVariables;
int loop1, loop2;
StringBuilder serverVariableKeys = new StringBuilder();
Exception exception = Server.GetLastError();
HttpException httpException = exception as HttpException;
if (HttpContext.Current != null)
{
// loop through and get server vars
}
if (exception != null)
// Log Error
// Redirect to Error page if set to basic mode
if (!string.IsNullOrWhiteSpace(displayError) && displayError.ToLower() == "basic")
{
Response.Clear();
Server.ClearError(); // needed for redirect to work
var routeData = new RouteData();
routeData.Values["controller"] = "Error";
routeData.Values["action"] = "General";
routeData.Values["exception"] = exception;
Response.StatusCode = 500;
if (httpException != null)
{
Response.StatusCode = httpException.GetHttpCode();
switch (Response.StatusCode)
{
case 403:
routeData.Values["action"] = "Http403";
break;
case 404:
routeData.Values["action"] = "Http404";
break;
}
}
IController errorsController = new Controllers.ErrorController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
}
У меня есть ErrorController
, который имеет General
, Http403
и Http404
Действия. У меня есть мнения, соответствующие каждому действию.
В моем web.config у меня есть:
<system.web>
<!-- removed bits to reduce space -->
<customErrors mode="On" />
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules >
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
<remove name="Session"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule" preCondition=""/>
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<httpErrors errorMode="Detailed" />
</system.webServer>
Это работает для многих сценариев, связанных с управляемым кодом, но когда IIS берет на себя, например, плохой статический вызов файла (example.com/BadFileName.gif), он возвращает ошибку из IIS, которая раскрывает данные сервера, такие как путь к локальному файлу, Это происходит из-за следующей строки в файле web.config:
<httpErrors errorMode="Detailed" />
Но когда я устанавливаю значение errorMode для других значений, таких как Custom, или просто удаляю строку, моя пользовательская обработка ошибок перестает работать, и сообщения об ошибках IIS по умолчанию возвращаются для всех, включая ошибки управляемого кода.
Я пробовал несколько вещей, чтобы добраться до пользовательских ошибок, чтобы работать без этого параметра без везения, в том числе:
- Настройка
CustomError
-mode="Off"
- Определение узлов ошибок в
CustomError
для перенаправления на мои контроллеры - Определение узлов ошибок в
httpErrors
для перенаправления на мои контроллеры
Когда я перехожу к отладке, я вижу вызов контроллера, но в конце IIS вместо этого отправляет ответ. Ведение журнала ошибок правильно вызвано Application_Error, поэтому код позволяет приложению обрабатывать его до определенной точки.
Сведения о приложении:
- ASP.NET MVC 4.0
- Хостинг на IIS 7.5 (Предварительный просмотр веб-сайта Azure)
Есть ли способ не использовать <httpErrors errorMode="Detailed" />
и сделать эту работу?