Пользовательские страницы ошибок ASP.NET MVC с Magical Unicorn

мой вопрос касается ответа Pure.Kromes на этот пост < / а>. Я попытался реализовать настраиваемые сообщения об ошибках на своих страницах, используя его метод, но есть некоторые проблемы, которые я не могу объяснить.

a) Когда я вызываю ошибку 404, вводя недопустимый URL-адрес, например localhost: 3001 / NonexistantPage, по умолчанию используется действие ServerError () моего контроллера ошибок, хотя он должен перейти в NotFound (). Вот мой ErrorController:

    public class ErrorController : Controller
    {
        public ActionResult NotFound()
        {
            Response.TrySkipIisCustomErrors = true;
            Response.StatusCode = (int)HttpStatusCode.NotFound;
            var viewModel = new ErrorViewModel()
            {
                ServerException = Server.GetLastError(),
                HTTPStatusCode = Response.StatusCode
            };
            return View(viewModel);
        }

        public ActionResult ServerError()
        {
            Response.TrySkipIisCustomErrors = true;
            Response.StatusCode = (int)HttpStatusCode.InternalServerError;

            var viewModel = new ErrorViewModel()
            {
                ServerException = Server.GetLastError(),
                HTTPStatusCode = Response.StatusCode
            };
            return View(viewModel);
        }
    }

Мои маршруты ошибок в Global.asax.cs:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

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

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


И мои настройки web.config:

<system.web>
    <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="/ServerError">
    <error statusCode="404" redirect="/NotFound" />
</customErrors>
...
</system.web>

<system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="404" subStatusCode="-1" />
      <error statusCode="404" path="/NotFound" responseMode="ExecuteURL" />
      <remove statusCode="500" subStatusCode="-1" />
      <error statusCode="500" path="/ServerError" responseMode="ExecuteURL" />
</httpErrors>
...

Представления ошибок расположены в / Views / Error / как NotFound.cshtml и ServerError.cshtml.

б) Одна забавная вещь: когда возникает ошибка сервера, он фактически отображает определенное мной представление ошибок сервера, однако также выводит сообщение об ошибке по умолчанию, а также сообщение о том, что страница ошибки не может быть найдена.

Вот как это выглядит:


Есть ли у вас какие-нибудь советы, как я могу решить эти две проблемы? Мне очень нравится подход Pure.Kromes к реализации этих сообщений об ошибках, но если есть более эффективные способы достижения этого, не стесняйтесь сказать мне.

Спасибо!

** РЕДАКТИРОВАТЬ: ** Я могу напрямую перейти к своим представлениям через ErrorController, открыв / Error / NotFound или Error / ServerError.

Сами представления содержат только текст, без разметки или чего-то еще.

Как я уже сказал, это действительно работает каким-то образом, но не так, как я предполагал. Кажется, есть проблема с перенаправлением в web.config, но я не смог ее понять.


person FLClover    schedule 31.10.2012    source источник
comment
Вы тоже можете публиковать свои мнения? Также не забудьте удалить это GlobalFilters.Filters.Add(new HandleErrorAttribute());   -  person Nate-Wilkins    schedule 09.11.2012
comment
Можете ли вы перейти прямо на свою страницу 404?   -  person Pete - MSFT    schedule 12.11.2012
comment
Да, я могу. Проблема здесь, похоже, связана с настройками в web.config, хотя я не могу найти там ошибку.   -  person FLClover    schedule 12.11.2012


Ответы (2)


есть еще одна проблема с этой настройкой, когда у вас есть более сложные маршруты и несколько сегментов, например.

http://localhost:2902/dsad/dadasdmasda/ddadad/dadads/ddadad/dadadadad/

У меня ошибка сервера ->

Sorry, an error occurred while processing your request.


Exception: An error occured while trying to Render the custom error view which you provided, for this HttpStatusCode. ViewPath: ~/Views/Error/NotFound.cshtml; Message: The RouteData must contain an item named 'controller' with a non-empty string value.
Source: 

Мое решение для этого заключалось в том, чтобы добавить дополнительный маршрут в конце после маршрута по умолчанию

        routes.MapRoute(
            "Default Catch all 404",
            "{controller}/{action}/{*catchall}",
            new { controller = "Error", action = "NotFound" }
        );

надеюсь, что это может кому-то помочь :-)

person krknapik14    schedule 19.12.2012
comment
Ты прав. Я также включу это в свои маршруты. Спасибо! - person FLClover; 21.12.2012

Я заставил его работать. Похоже, я изначально неправильно понимал проблему.

В web.config я изменил следующее:

<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Views/Error/ServerError.cshtml">
  <error statusCode="404" redirect="~/Views/Error/NotFound.cshtml" />
</customErrors>

... и ...

<httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="404" subStatusCode="-1" />
      <error statusCode="404" path="/NotFound" responseMode="ExecuteURL" />
      <remove statusCode="500" subStatusCode="-1" />
      <error statusCode="500" path="/ServerError" responseMode="ExecuteURL" />
    </httpErrors>

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

person FLClover    schedule 12.11.2012