2016-07-07 2 views
4

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

Asp.net Обработка ошибок

<customErrors mode="On" redirectMode="ResponseRewrite"> 
    <error statusCode="404" redirect="~/404.aspx"/> 
</customErrors> 

Ошибка IIS Обработка

<httpErrors errorMode="Custom"> 
    <remove statusCode="404"/> 
    <error statusCode="404" path="/404.html" responseMode="File"/> 
</httpErrors> 

Есть ли способ реализации динамических страниц ошибок, которые могут работать как для IIS ошибки и ошибки ASP.Net?

+0

Взгляните на мое предложение и посмотрите, можно ли его применить в вашем сценарии. – Nkosi

ответ

1

У меня есть одна и та же проблема в проектах ASP.Net MVC, прокладывая все через .Net через обработчики.

<system.webServer> 
    <handlers> 
     <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" /> 
     <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" /> 
     <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
     <remove name="OPTIONSVerbHandler" /> 
     <remove name="TRACEVerbHandler" /> 
     <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*.*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> 
     <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*.*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> 
     <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*.*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
    </handlers> 
    </system.webServer> 

Первый ErrorController был создан для обработки ошибок запроса и не найдены запросы нравится.

[AllowAnonymous] 
public class ErrorController : Controller { 
    // GET: Error 
    public ActionResult NotFound() { 
     Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound; 
     Response.TrySkipIisCustomErrors = true; 
     HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound; 
     HttpContext.Response.TrySkipIisCustomErrors = true; 
     return View(); 
    } 

    public ActionResult Error() { 
     Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError; 
     Response.TrySkipIisCustomErrors = true; 
     return View(); 
    } 
} 

Вы заметите, что я называю TrySkipIisCustomErrors, чтобы попытаться избежать ошибок IIS

Затем базовый контроллер для обработки всех неизвестных действий, которые сопоставляют к ErrorController.NotFound действий была создана.

public abstract class FrontOfficeControllerBase : Controller { 
    protected override void HandleUnknownAction(string actionName) { 
     var data = ViewData; 
     //Custom code to resolve the view. 
     //ViewResult view = this.View<ErrorController>(c => c.NotFound()); 

     //Manually create view with view Data 
     ViewResult view = new ViewResult(); 
     view.ViewData = new ViewDataDictionary(); 
     view.ViewData["controller"] = "Error"; 
     view.ViewData["action"] = "NotFound"; 

     if (data != null && data.Count > 0) { 
      data.ToList().ForEach(view.ViewData.Add); 
     } 

     Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound; 
     Response.TrySkipIisCustomErrors = true; 
     view.ExecuteResult(this.ControllerContext); 
    } 
} 

Все Controllers унаследовали бы от этого базового контроллера.

Улавливать весь маршрут был настроен после всех других маршрутов.

routes.MapRoute(
    name: "404-NotFound", 
    url: "NotFound", 
    defaults: new { controller = "Error", action = "NotFound" } 
); 

routes.MapRoute(
    name: "500-Error", 
    url: "Error", 
    defaults: new { controller = "Error", action = "Error" } 
); 

routes.MapRoute(
    name: "CatchAll", 
    url: "{*any}", 
    defaults: new { controller = "Error", action = "NotFound" }); 

Это сделано в том, что если маршрут не соответствует ни одному из моих контроллеров это будет безопасно путь к ErrorController.NotFound действия.

Для взглядов, я создал соответствующий NotFound.shtml и Error.cshtml выгружаемых в папке Views/Shared, и они воспользовались доступом к корневому макету, что то, что я думаю, что вы искали.

В конце концов, я был в состоянии удалить как customErrors и httpErrors из web.config, как там уже не было никакой необходимости в них, как каждый запрос управлял обработчиками и направляется соответственно.

Исходная идея для этой структуры взята из этой статьи, где я смешивал и сопоставлял доступные варианты, пока не нашел решение, которое работало/соответствовало моим потребностям.

Exception handling in ASP.NET MVC (6 methods explained)

Надеется, что это помогает.

+0

Пойдем, чтобы отдать это и отчитаться. Благодаря! –

+0

Таким образом, только два способа, которыми я смог заставить это работать, - использовать ViewResult view = new ErrorsController (this.ControllerContext) .NotFound(); который по какой-то причине приводит к тому, что он игнорирует метод переопределения, который я не совсем уверен, что понимаю, поскольку другой способ привел к нулевому контексту для контроллера, но нашел HandleUnknownAction. Сам код, похоже, зависит от этого .View , однако я не могу все равно выполнить эту операцию, так как View не может принять аргумент типа. –

+0

С небольшим количеством настроек из-за определенных предметов, я нашел, что это сработало и определенно порекомендует его другим! –

4

Я тоже боролся с этим и искал долгое время. Насколько я могу судить, нет возможности создать динамическую страницу пользовательских ошибок, которая будет обслуживаться для ошибок IIS для запросов, которые не входят в конвейер .net. Как и вы, у меня было две 404 страницы ошибок. Один динамический .aspx один для файла не обнаруживает ошибок, возникающих в результате запросов, которые вступили в .net-конвейер, и один .html один для файлов, не найденных запросов, которые никогда не вошли в .net-конвейер. Человек, который отклонил ваш вопрос, вероятно, не понимал, что вы задаете очень хороший и сложный вопрос, который не имеет простого решения. Я отвечу на ваш вопрос, чтобы помочь компенсировать.

+0

Я потратил время на поиск, но только когда-либо находил ответы, указывающие на статические страницы, как на то, чтобы идти. Меня беспокоило, что я, возможно, не задаю правильный вопрос, так что спасибо за облегчение моих проблем. Я буду придерживаться статических страниц и делать все, что от меня! –

+0

@RonC, взгляните на мое предложение и посмотрите, можно ли его применить в этом сценарии. – Nkosi

+1

@Nkoshi - Не делая глубокого погружения в ваш код, я согласен с тем, что одна потенциальная работа заключается в том, чтобы направлять * все * запросы в конвейер с точечной сетью. В таком случае все 404 могут обрабатываться динамической страницей .aspx. Он не решает корневую проблему того, как обслуживать динамическую страницу aspx для ошибок IIS, которые не маршрутизируются в конвейер. Кроме того, обычные * все * запросы (изображения и т. Д.) Через конвейер .net накладывают большую нагрузку на сервер, что многие разработчики могут не захотеть (включая меня). В стороне, я направляю .html запросы по конвейеру для обработки их ошибок. –

Смежные вопросы