de-vraag
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
 Clearly
Clearly
Вопрос

Обработка 404 ошибки ASP.NET MVC

Возможный дубликат: Как правильно обрабатывать 404 в ASP.NET MVC?

Я'сделал изменения, описанные на https://stackoverflow.com/questions/108813/404-http-error-handler-in-aspnet-mvc-rc-5, но все равно получаю стандартную страницу ошибки 404. Нужно ли мне что-то изменить в IIS?

129 2009-04-04T19:13:25+00:00 6
Valeriu
Valeriu 52848
Редактировал вопрос 29-го сентября 2021 в 5:51
 Community
Community
Редактировал вопрос 23-го мая 2017 в 12:10
Программирование
asp.net-mvc
error-handling
 Marco
Marco
26-го января 2012 в 11:16
2012-01-26T23:16:37+00:00
Дополнительно
Источник
Редактировать
#8952260

Я изучил А МНОГО о том, как правильно управлять 404s в MVC (особенно MVC3), и это, IMHO, лучшее решение, которое я придумал:

В global.asax:

public class MvcApplication : HttpApplication
{
    protected void Application_EndRequest()
    {
        if (Context.Response.StatusCode == 404)
        {
            Response.Clear();

            var rd = new RouteData();
            rd.DataTokens["area"] = "AreaName"; // In case controller is in another area
            rd.Values["controller"] = "Errors";
            rd.Values["action"] = "NotFound";

            IController c = new ErrorsController();
            c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
        }
    }
}

ErrorsController:

public sealed class ErrorsController : Controller
{
    public ActionResult NotFound()
    {
        ActionResult result;

        object model = Request.Url.PathAndQuery;

        if (!Request.IsAjaxRequest())
            result = View(model);
        else
            result = PartialView("_NotFound", model);

        return result;
    }
}

Правка:.

Если вы используете IoC (например, AutoFac), вы должны создать свой контроллер, используя:

var rc = new RequestContext(new HttpContextWrapper(Context), rd);
var c = ControllerBuilder.Current.GetControllerFactory().CreateController(rc, "Errors");
c.Execute(rc);

вместо

IController c = new ErrorsController();
c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));

(Необязательно)

Пояснение:

Существует 6 сценариев, в которых приложения ASP.NET MVC3 могут генерировать 404s.

Генерируется ASP.NET:

  • Сценарий 1: URL не соответствует маршруту в таблице маршрутов.

Генерируется ASP.NET MVC:

  • Сценарий 2: URL соответствует маршруту, но указывает несуществующий контроллер.

  • Сценарий 3: URL соответствует маршруту, но указывает несуществующее действие.

Создано вручную:

  • Сценарий 4: Действие возвращает результат HttpNotFoundResult с помощью метода HttpNotFound().

  • Сценарий 5: Действие выбрасывает HttpException с кодом состояния 404.

  • Сценарий 6: Действие вручную изменяет свойство Response.StatusCode на 404.

Цели

  • (A) Показать пользователю пользовательскую страницу ошибки 404.

  • (B) Сохранить код статуса 404 в ответе клиента (особенно важно для SEO).

  • (C) Отправить ответ напрямую, без использования 302 перенаправления.

Попытка решения: Пользовательские ошибки

<system.web>
    <customErrors mode="On">
        <error statusCode="404" redirect="~/Errors/NotFound"/>
    </customErrors>
</system.web>

Проблемы с этим решением:

  • Не соответствует цели (A) в сценариях (1), (4), (6).
  • Не соответствует цели (B) автоматически. Его необходимо запрограммировать вручную.
  • Не соответствует цели (C).

Попытка решения: Ошибки HTTP

<system.webServer>
    <httpErrors errorMode="Custom">
        <remove statusCode="404"/>
        <error statusCode="404" path="App/Errors/NotFound" responseMode="ExecuteURL"/>
    </httpErrors>
</system.webServer>

Проблемы с этим решением:

  • Работает только на IIS 7+.
  • Не соответствует цели (A) в сценариях (2), (3), (5).
  • Не соответствует цели (B) автоматически. Его необходимо запрограммировать вручную.

Попытка решения: Ошибки HTTP с заменой.

<system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
        <remove statusCode="404"/>
        <error statusCode="404" path="App/Errors/NotFound" responseMode="ExecuteURL"/>
    </httpErrors>
</system.webServer>

Проблемы с этим решением:

  • Работает только на IIS 7+.
  • Не соответствует цели (B) автоматически. Его необходимо программировать вручную.
  • Затушевывает http-исключения на уровне приложения. Например, не может использовать секцию customErrors, System.Web.Mvc.HandleErrorAttribute и т.д. Он не может показывать только общие страницы ошибок.

Решение Попытка customErrors и HTTP Errors.

<system.web>
    <customErrors mode="On">
        <error statusCode="404" redirect="~/Errors/NotFound"/>
    </customError>
</system.web>

и

<system.webServer>
    <httpErrors errorMode="Custom">
        <remove statusCode="404"/>
        <error statusCode="404" path="App/Errors/NotFound" responseMode="ExecuteURL"/>
    </httpErrors>
</system.webServer>

Проблемы с этим решением:

  • Работает только на IIS 7+.
  • Не соответствует цели (B) автоматически. Его необходимо запрограммировать вручную.
  • Не соответствует цели (C) в сценариях (2), (3), (5).

Люди, которые уже сталкивались с этой проблемой, даже пытались создать свои собственные библиотеки (см. http://aboutcode.net/2011/02/26/handling-not-found-with-asp-net-mvc3.html). Но предыдущее решение, кажется, покрывает все сценарии без сложности использования внешней библиотеки.

Valeriu
Valeriu 52848
Редактировал ответ 29-го сентября 2021 в 5:51
362
0
Решение / Ответ
Mike Chaliy
Mike Chaliy
4-го апреля 2009 в 8:04
2009-04-04T20:04:56+00:00
Дополнительно
Источник
Редактировать
#8952258

Еще одно решение.

Добавьте ErrorControllers или статическую страницу с информацией об ошибке 404.

Измените ваш web.config (в случае контроллера).

<system.web>
    <customErrors mode="On" >
       <error statusCode="404" redirect="~/Errors/Error404" />
    </customErrors>
</system.web>

Или в случае статической страницы

<system.web>
    <customErrors mode="On" >
        <error statusCode="404" redirect="~/Static404.html" />
    </customErrors>
</system.web>

Это позволит обрабатывать как пропущенные маршруты, так и пропущенные действия.

Valeriu
Valeriu 52848
Редактировал ответ 29-го сентября 2021 в 5:51
142
0
 Yousi
Yousi
11-го апреля 2012 в 1:03
2012-04-11T13:03:02+00:00
Дополнительно
Источник
Редактировать
#8952263

Ответ Марко - это ЛУЧШЕЕ решение. Мне нужно было контролировать обработку ошибок, и я имею в виду действительно КОНТРОЛИРОВАТЬ ее. Конечно, я немного расширил это решение и создал полную систему управления ошибками, которая управляет всем. Я также читал об этом решении в других блогах, и оно кажется очень приемлемым для большинства продвинутых разработчиков.

Вот окончательный код, который я использую:

protected void Application_EndRequest()
    {
        if (Context.Response.StatusCode == 404)
        {
            var exception = Server.GetLastError();
            var httpException = exception as HttpException;
            Response.Clear();
            Server.ClearError();
            var routeData = new RouteData();
            routeData.Values["controller"] = "ErrorManager";
            routeData.Values["action"] = "Fire404Error";
            routeData.Values["exception"] = exception;
            Response.StatusCode = 500;

            if (httpException != null)
            {
                Response.StatusCode = httpException.GetHttpCode();
                switch (Response.StatusCode)
                {
                    case 404:
                        routeData.Values["action"] = "Fire404Error";
                        break;
                }
            }
            // Avoid IIS7 getting in the middle
            Response.TrySkipIisCustomErrors = true;
            IController errormanagerController = new ErrorManagerController();
            HttpContextWrapper wrapper = new HttpContextWrapper(Context);
            var rc = new RequestContext(wrapper, routeData);
            errormanagerController.Execute(rc);
        }
    }

и внутри моего ErrorManagerController :

        public void Fire404Error(HttpException exception)
    {
        //you can place any other error handling code here
        throw new PageNotFoundException("page or resource");
    }

Теперь, в моем Action, я бросаю пользовательское исключение, которое я создал. А мой контроллер наследуется от созданного мной пользовательского класса Controller Based. Пользовательский базовый контроллер был создан для переопределения обработки ошибок. Вот мой пользовательский класс базового контроллера:

public class MyBasePageController : Controller
{
    protected override void OnException(ExceptionContext filterContext)
    {
        filterContext.GetType();
        filterContext.ExceptionHandled = true;
        this.View("ErrorManager", filterContext).ExecuteResult(this.ControllerContext);
        base.OnException(filterContext);
    }
}

ErrorManager" в приведенном выше коде - это просто представление, которое использует модель, основанную на ExceptionContext.

Мое решение отлично работает, и я могу обрабатывать ЛЮБЫЕ ошибки на моем сайте и отображать различные сообщения, основанные на ЛЮБОМ типе исключения.

Valeriu
Valeriu 52848
Редактировал ответ 29-го сентября 2021 в 5:50
5
0
 Clearly
Clearly
4-го апреля 2009 в 8:02
2009-04-04T20:02:03+00:00
Дополнительно
Источник
Редактировать
#8952257

Похоже, это лучший способ поймать все.

https://stackoverflow.com/questions/619895/how-can-i-properly-handle-404s-in-asp-net-mvc

Valeriu
Valeriu 52848
Редактировал ответ 29-го сентября 2021 в 5:50
4
0
 J.W.
J.W.
4-го апреля 2009 в 7:33
2009-04-04T19:33:16+00:00
Дополнительно
Источник
Редактировать
#8952254

В IIS можно задать перенаправление на "определенную" страницу на основе кода ошибки. В вашем примере вы можете настроить 404 - > Ваша настраиваемая страница ошибки 404.

Valeriu
Valeriu 52848
Редактировал ответ 29-го сентября 2021 в 5:50
1
0
Mike Chaliy
Mike Chaliy
4-го апреля 2009 в 7:43
2009-04-04T19:43:47+00:00
Дополнительно
Источник
Редактировать
#8952255

Что я могу порекомендовать, так это посмотреть на FilterAttribute. Например, в MVC уже есть атрибут HandleErrorAttribute. Вы можете настроить его на обработку только 404. Если вам интересно, напишите, я посмотрю пример.

BTW

Решение (с последним маршрутом), которое вы приняли в предыдущем вопросе, не работает в большинстве ситуаций. Второе решение с HandleUnknownAction будет работать, но требует внесения этого изменения в каждый контроллер или иметь один базовый контроллер.

Мой выбор - решение с HandleUnknownAction.

Valeriu
Valeriu 52848
Редактировал ответ 29-го сентября 2021 в 5:49
1
0
Похожие сообщества 13
DotNetRuChat
DotNetRuChat
6 639 пользователей
Чат русскоязычного .NET сообщества http://dotnet.ru/ Правила: https://t.me/DotNetRuChat/704399 Вам могут быть интересны: @dotnetchat, @cilchat, @fsharp_chat, @pro_net, @AvaloniaRU, @xamarin_russia, @DotNetRuJobs, @uwp_ru Флуд в @dotnettalks
Открыть telegram
Вакансии .NET
Вакансии .NET
3 220 пользователей
Правила: https://t.me/DotNetRuJobs/123 Канал с вакансиями - https://t.me/DotNetRuJobsFeed Вам могут быть интересны: @dotnetruchat, @cilchat, @fsharp_chat, @pro_net, @AvaloniaRU, @xamarin_russia Флуд в @dotnettalks
Открыть telegram
pro.net
pro.net
1 758 пользователей
Обсуждение .NET и всего, что с ним связано. Правила: не флудить не по теме, уважать ваших коллег и никакой рекламы (объявления о вакансиях можно согласовать с @AlexFails). https://t.me/pro_net/34653 Флудилка: @dotnettalks
Открыть telegram
var chat = new Chat();
var chat = new Chat();
1 260 пользователей
Обсуждение вопросов по .NET Правила чата – https://blog.devdigest.today/chat-rules Чат для флуда – https://t.me/+MXQZTV9pdq5hM2Ri
Открыть telegram
.NET Talks - Tajvan je Kina
.NET Talks - Tajvan je Kina
1 232 пользователей
Свободный чат .NET разработчиков. Правила: https://t.me/dotnettalks/548269 Вам могут быть интересны: @dotnetruchat, @dotnetchat, @cilchat, @fsharp_chat, @pro_net, @dotnetgroup, @xamarin_russia, @DotNetRuJobs, @uwp_ru, @AvaloniaRu, @dotnettalksenglish
Открыть telegram
Чат конференции DotNext
Чат конференции DotNext
1 025 пользователей
Канал конференции: @dotnext_channel Ближайшая конференция — DotNext 2022 Spring, 16–17 июня, онлайн Билеты: https://tinyurl.com/DotNext2022Spring Больше конференций: https://tinyurl.com/FullPass2022Spring Саппорт: @JUGConfSupport_bot
Открыть telegram
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Roxana Elizabeth CASTILLO Avalos
Зарегистрирован 23 часа назад
2
Hideo Nakagawa
Зарегистрирован 1 день назад
3
Sergiy Tytarenko
Зарегистрирован 3 дня назад
4
shoxrux azadov
Зарегистрирован 5 дней назад
5
Koreets Koreytsev
Зарегистрирован 1 неделю назад
ID
JA
RU
© de-vraag 2022
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией