Можно ли использовать персонализированные страницы ошибок с сайтом MVC, но не Web API?
У меня есть проект MVC с папкой /api, которая содержит мои контроллеры Web API. Я хочу следующее:
- Мой сайт MVC для обслуживания страницы пользовательских ошибок при возникновении ошибки
- Мой веб-API для обслуживания ответа об ошибке по умолчанию (json/xml, содержащий исключение и трассировку стека)
В web.config для моего сайта MVC у меня есть httpErrors node и установите для параметра errorMode значение "Пользовательский", чтобы у меня были хорошие страницы ошибок, когда 404s/500s/etc. при просмотре сайта MVC:
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<remove statusCode="403" subStatusCode="-1" />
<error prefixLanguageFilePath="" statusCode="404" path="Content\notfound.htm" responseMode="File" />
<error statusCode="500" path="/Errors" responseMode="ExecuteURL" />
<error statusCode="403" path="/Errors/Http403" responseMode="ExecuteURL" /></httpErrors>
Однако при такой конфигурации API будет обслуживать страницу пользовательских ошибок при возникновении ошибки, а не json/xml с трассировкой exception/stack (что является желаемым поведением).
Есть ли способ настроить собственные ошибки только для моего MVC-сайта, а не для Web API? Этот блог говорит, что нет (http://blog.kristandyson.com/2012/11/iis-httperrors-aspnet-web-api-fully.html), но я хотел бы услышать, если кто-то еще нашел работу, поскольку этот блог был опубликован.
Я полагаю, что если бы я не мог создать отдельный проект/сборку для моего проекта веб-API. Это позволило бы мне настроить HTTPErrors для MVC и веб-API отдельно, но я бы предпочел не создавать другой проект, так что у меня есть еще один конфигуратор web.config.
Ответы
Ответ 1
Хорошо, после почти года разрешения этого вопроса маринад я дал ему еще один выстрел. Вот волшебство web.config, которое получило меня, что я хотел:
<!-- inside of <configuration> to allow error
responses from requests to /api through -->
<location path="api">
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough" >
<clear/>
</httpErrors>
</system.webServer>
</location>
<!-- original httpErrors, inside of <location path="." inheritInChildApplications="false">
to serve custom error pages when the MVC site returns an error code -->
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="400" subStatusCode="-1" />
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<remove statusCode="403" subStatusCode="-1" />
<error statusCode="400" prefixLanguageFilePath="" path="Content\notfound.htm" responseMode="File"/>
<error prefixLanguageFilePath="" statusCode="404" path="Content\notfound.htm" responseMode="File" />
<error statusCode="500" path="/errors" responseMode="ExecuteURL" />
<error statusCode="403" path="/errors/http403" responseMode="ExecuteURL" />
</httpErrors>
Суть в том, что здесь происходит, заключается в том, что <location>
node позволяет переопределить настройки, сделанные на менее конкретном пути. Таким образом, хотя у нас есть errorMode = "Custom" для path = ".", Мы переопределяем это для нашего пути веб-API с <location path="api">
node и конфигурацией httpErrors внутри него.
Я видел узлы раньше, но мне не дошло, что это их цель до сих пор. В этой статье мы подробно рассмотрим конфигурационную модель наследования IIS/.NET, которую я нашел очень информативной: http://weblogs.asp.net/jongalloway/10-things-asp-net-developers-should-know-about-web-config-inheritance-and-overrides
Ответ 2
Я не тестировал это, но как насчет написания кода для обработки ошибок вашего MVC-приложения, как показано здесь http://thirteendaysaweek.com/2012/09/25/custom-error-page-with-asp-net-mvc-4/?
Его код показывает, что он делает это на уровне приложения (Global.asax), но, я думаю, вы могли бы также исключать ловушку на более низком уровне таким же образом, используя один метод для MVC и другой для Web API.