Я использую RC2
Использование маршрутизации URL:
routes.MapRoute(
"Error",
"{*url}",
new { controller = "Errors", action = "NotFound" } // 404s
);
Вышеприведенное, кажется, заботится о таких запросах (при условии, что таблицы маршрутов по умолчанию настроены первоначальным проектом MVC): "/ бла / бла / бла / бла"
Переопределение HandleUnknownAction () в самом контроллере:
// 404s - handle here (bad action requested
protected override void HandleUnknownAction(string actionName) {
ViewData["actionName"] = actionName;
View("NotFound").ExecuteResult(this.ControllerContext);
}
Однако предыдущие стратегии не обрабатывают запрос к плохому / неизвестному контроллеру. Например, у меня нет «/ IDoNotExist», если я запрашиваю это, я получаю общую страницу 404 с веб-сервера, а не мою 404, если я использую маршрутизацию + переопределение.
Итак, наконец, мой вопрос: есть ли способ перехватить этот тип запроса, используя маршрут или что-то еще в самой структуре MVC?
ИЛИ мне просто по умолчанию использовать Web.Config customErrors в качестве моего обработчика 404 и забыть все это? Я предполагаю, что если я пойду с customErrors, мне придется хранить общую страницу 404 вне / Views из-за ограничений Web.Config на прямой доступ.
Ответы:
Код взят из http://blogs.microsoft.co.il/blogs/shay/archive/2009/03/06/real-world-error-hadnling-in-asp-net-mvc-rc2.aspx и работает в ASP.net MVC 1.0, а также
Вот как я обрабатываю исключения http:
источник
Требования к 404
Ниже приведены мои требования к решению 404, и ниже я покажу, как я его реализую:
Решение
Я думаю, что вы должны сохранить
Application_Error
в Global.asax более высокие вещи, такие как необработанные исключения и ведение журнала (как показывает ответ Шей Джейкоби ), но не обработку 404. Вот почему мое предложение не позволяет использовать 404 в файле Global.asax.Шаг 1: Иметь общее место для логики с 404 ошибками
Это хорошая идея для ремонтопригодности. Используйте ErrorController, чтобы будущие улучшения вашей хорошо спроектированной страницы 404 могли легко адаптироваться. Кроме того, убедитесь, что ваш ответ имеет код 404 !
Шаг 2: Используйте базовый класс Controller, чтобы вы могли легко вызвать свое собственное действие 404 и подключиться
HandleUnknownAction
404-е в ASP.NET MVC нужно ловить в нескольких местах. Первый есть
HandleUnknownAction
.InvokeHttp404
Метод создает общее место для повторной маршрутизации кErrorController
и нашему новомуHttp404
действию. Думай СУХОЙ !Шаг 3: Используйте Dependency Injection в вашей фабрике контроллеров и подключите 404 HttpExceptions
Вот так (это не обязательно должен быть StructureMap):
Пример MVC1.0:
Пример MVC2.0:
Я думаю, что лучше ловить ошибки ближе к месту их возникновения. Вот почему я предпочитаю вышесказанное
Application_Error
обработчику.Это второе место для ловли 404-х годов.
Шаг 4. Добавьте NotFound маршрут в Global.asax для URL-адресов, которые не могут быть проанализированы в вашем приложении.
Этот маршрут должен указывать на наши
Http404
действия. Заметьте, чтоurl
параметр будет относительным URL, потому что механизм маршрутизации удаляет здесь доменную часть? Вот почему у нас есть вся эта условная логика URL на шаге 1.Это третье и последнее место, где можно поймать 404-е в приложении MVC, которое вы сами не вызываете. Если вы не поймаете несопоставленные маршруты здесь, то MVC передаст проблему в ASP.NET (Global.asax), и вы действительно не хотите этого в этой ситуации.
Шаг 5. Наконец, вызовите 404s, когда ваше приложение не может найти что-то
Например, когда мой контролер Loans отправляет неверный идентификатор (происходит из
MyController
):Было бы неплохо, если бы все это можно было подключить в меньшем количестве мест с меньшим количеством кода, но я думаю, что это решение более легко обслуживаемо, более тестируемо и довольно прагматично.
Спасибо за отзыв до сих пор. Я хотел бы получить больше.
ПРИМЕЧАНИЕ: это было значительно отредактировано из моего первоначального ответа, но цель / требования те же - поэтому я не добавил новый ответ
источник
customErrors
Раздел web.config определяет статические страницы перенаправления, которые обрабатываются на высоком уровне в aspnet, если не в IIS. Это не то, что я хотел, так как мне нужно было иметь MVC Views (чтобы я мог иметь в них данные и т. Д.). Я бы не сказал категорически, что «customErrors
устарел в MVC», но для меня и этого решения 404 они, безусловно, есть.ObjectFactory.GetInstance
на MVC3DependencyResolver.Current.GetService
вместо этого, чтобы он был более общим. Я использую Ninject.ASP.NET MVC не очень хорошо поддерживает пользовательские страницы 404. Кастомная фабрика контроллеров, универсальный маршрут, базовый класс контроллеров с
HandleUnknownAction
- аааа!Пользовательские страницы ошибок IIS пока являются лучшей альтернативой:
web.config
ErrorController
Пример проекта
источник
customErrors mode="On"
вместе сHandleErrorAttribute
быть функциональным. Пользовательские страницы ошибок для необработанных исключений в действиях контроллера больше не обслуживаются.Быстрый ответ / TL; DR
Для ленивых людей там:
Затем удалите эту строку из
global.asax
И это только для IIS7 + и IIS Express.
Если вы используете Кассини .. ну .. эм .. эээ ... неловко ...
Долго объяснил ответ
Я знаю, что на это ответили. Но ответ ДЕЙСТВИТЕЛЬНО ПРОСТО (приветствует Дэвида Фаулера и Дамиана Эдвардса за то, что он действительно ответил на это).
Там нет необходимости делать что-либо на заказ .
За
ASP.NET MVC3
все кусочки есть.Шаг 1 -> Обновите ваш web.config в двух местах.
а также
Теперь внимательно обратите внимание на МАРШРУТЫ, которые я решил использовать. Вы можете использовать что угодно, но мои маршруты
/NotFound
<- для 404 не найдено, страница ошибки./ServerError
<- для любой другой ошибки, включите ошибки, которые происходят в моем коде. это 500 внутренняя ошибка сервераВидите, как в первом разделе
<system.web>
есть только одна пользовательская запись?statusCode="404"
Запись? Я перечислил только один код состояния, потому что все остальные ошибки, в том числе500 Server Error
(т.е. те неприятные ошибки, которые возникают, когда в вашем коде возникает ошибка и происходит сбой запроса пользователя) ... все остальные ошибки обрабатываются настройкойdefaultRedirect="/ServerError"
... которая говорит , если вы не нашли страницу 404, то пройдите по маршруту/ServerError
.Хорошо. это вне пути .. теперь к моим маршрутам, перечисленным в
global.asax
Шаг 2 - Создание маршрутов в Global.asax
Вот мой полный раздел маршрута ..
Это перечисляет два маршрута игнорирования ->
axd's
иfavicons
(ooo! Бонус игнорировать маршрут, для вас!) Затем (и порядок здесь ИМПЕРАТИВНЫЙ ЗДЕСЬ), у меня есть два явных маршрута обработки ошибок ..., за которыми следуют любые другие маршруты. В этом случае по умолчанию. Конечно, у меня есть больше, но это специально для моего веб-сайта. Просто убедитесь, что маршруты ошибок находятся вверху списка. Порядок обязателен .Наконец, пока мы находимся внутри нашего
global.asax
файла, мы НЕ регистрируем глобально атрибут HandleError. Нет, нет, нет, сэр. Nadda. Нет. Nien. Negative. Noooooooooo ...Удалить эту строку из
global.asax
Шаг 3 - Создайте контроллер с методами действия
Теперь .. мы добавляем контроллер с двумя методами действия ...
Хорошо, давайте проверим это. Прежде всего, здесь нет
[HandleError]
атрибута. Почему? Потому что встроенный вASP.NET
фреймворк уже обрабатывает ошибки И мы указали все дерьмо, которое нам нужно сделать, чтобы обработать ошибку :) Именно в этом методе!Далее у меня есть два метода действия. Ничего сложного там нет. Если вы хотите показать какую-либо информацию об исключении, то вы можете использовать,
Server.GetLastError()
чтобы получить эту информацию.Бонус WTF: Да, я сделал третий метод действия, чтобы проверить обработку ошибок.
Шаг 4 - Создание представлений
И наконец, создайте два представления. Поместите их в обычное место просмотра для этого контроллера.
Бонусные комментарии
Application_Error(object sender, EventArgs e)
И это, друзья мои, должно быть так.
Теперь, поздравляю с чтением этого и единорог в качестве приза!
источник
?aspxerrorpath=/er/not/found
бы иметь в URL.Я исследовал МНОГО о том , как правильно управлять в MVC 404 - х ( в частности MVC3) , и это, ИМХО это лучшее решение , которое я придумал:
В global.asax:
ErrorsController:
(Необязательный)
Объяснение:
AFAIK, есть 6 различных случаев, когда приложения ASP.NET MVC3 могут генерировать 404.
(Автоматически генерируется ASP.NET Framework :)
(1) URL не находит соответствия в таблице маршрутов.
(Автоматически генерируется ASP.NET MVC Framework :)
(2) URL-адрес находит совпадение в таблице маршрутов, но указывает несуществующий контроллер.
(3) URL находит совпадение в таблице маршрутов, но указывает несуществующее действие.
(Генерируется вручную :)
(4) Действие возвращает HttpNotFoundResult с помощью метода HttpNotFound ().
(5) Действие выдает HttpException с кодом состояния 404.
(6) Действия вручную изменяют свойство Response.StatusCode на 404.
Обычно вы хотите выполнить 3 задачи:
(1) Показать пользовательскую страницу ошибки 404 пользователю.
(2) Сохраните код статуса 404 в ответе клиента (особенно важно для SEO).
(3) Отправьте ответ напрямую, без перенаправления 302.
Есть несколько способов сделать это:
(1)
Проблемы с этим решением:
(2)
Проблемы с этим решением:
(3)
Проблемы с этим решением:
(4)
а также
Проблемы с этим решением:
Люди, которые раньше сталкивались с этим, даже пытались создать свои собственные библиотеки (см. Http://aboutcode.net/2011/02/26/handling-not-found-with-asp-net-mvc3.html ). Но предыдущее решение, похоже, охватывает все случаи без сложности использования внешней библиотеки.
источник
public ActionResult NotFound() {}
в вашем ErrorsController. Кроме того, можете ли вы объяснить, как ваш_NotFound
частичный будет выглядеть для запросов AJAX?MissingMethodException: Cannot create an abstract class
в курсе.c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
Есть идеи?Мне действительно нравится решение коттсаков, и я думаю, что оно очень четко объяснено. мое единственное дополнение было изменить шаг 2 следующим образом
В основном это останавливает URL, содержащие недопустимые действия И контроллеры, от запуска процедуры исключения дважды. например, для URL, таких как asdfsdf / dfgdfgd
источник
Единственный способ заставить метод @ cottsak работать для недопустимых контроллеров - это изменить существующий запрос маршрута в CustomControllerFactory, например, так:
Я должен упомянуть, что я использую MVC 2.0.
источник
Вот еще один метод, использующий инструменты MVC, с помощью которого вы можете обрабатывать запросы к неверным именам контроллеров, неверным именам маршрутов и любым другим критериям, которые вы считаете подходящими внутри метода Action. Лично я предпочитаю избегать как можно большего числа настроек web.config, поскольку они выполняют перенаправление 302/200 и не поддерживают ResponseRewrite (
Server.Transfer
) с использованием представлений Razor. Я предпочел бы вернуть 404 с пользовательской страницей ошибок по причинам SEO.Отчасти это новый взгляд на технику Котцака выше.
Это решение также использует минимальные настройки web.config вместо фильтров ошибок MVC 3.
Применение
Просто сгенерируйте исключение HttpException из действия или пользовательского атрибута ActionFilterAttribute.
Шаг 1
Добавьте следующий параметр в ваш файл web.config. Это необходимо для использования HandleErrorAttribute MVC.
Шаг 2
Добавьте пользовательский атрибут HandleHttpErrorAttribute, аналогичный атрибуту HandleErrorAttribute инфраструктуры MVC, за исключением ошибок HTTP:
Шаг 3
Добавьте фильтры в GlobalFilterCollection (
GlobalFilters.Filters
) вGlobal.asax
. В этом примере все ошибки InternalServerError (500) будут перенаправлены в общее представление Error (Views/Shared/Error.vbhtml
). Ошибки NotFound (404) будут также отправляться в ErrorHttp404.vbhtml в общих представлениях. Я добавил ошибку 401, чтобы показать, как ее можно расширить для дополнительных кодов ошибок HTTP. Обратите внимание, что это должны быть общие виды, и все они используютSystem.Web.Mvc.HandleErrorInfo
объект в качестве модели.Шаг 4
Создайте базовый класс контроллеров и наследуйте его от своих контроллеров. Этот шаг позволяет нам обрабатывать неизвестные имена действий и выдавать ошибку HTTP 404 в наш атрибут HandleHttpErrorAttribute.
Шаг 5
Создайте переопределение ControllerFactory и переопределите его в файле Global.asax в Application_Start. Этот шаг позволяет нам вызвать исключение HTTP 404, когда было указано неверное имя контроллера.
Шаг 6
Включите специальный маршрут в свой RoutTable.Routes для действия BaseController Unknown. Это поможет нам поднять 404 в случае, когда пользователь получает доступ к неизвестному контроллеру или неизвестному действию.
Резюме
Этот пример продемонстрировал, как можно использовать инфраструктуру MVC для возврата 404 Http-кодов ошибок в браузер без перенаправления с использованием атрибутов фильтра и общих представлений ошибок. Он также демонстрирует отображение той же пользовательской страницы ошибок, когда указаны недопустимые имена контроллеров и имена действий.
Я добавлю скриншот недопустимого имени контроллера, имени действия и пользовательского 404, созданного из действия Home / TriggerNotFound, если я наберу достаточно голосов, чтобы опубликовать один =). Fiddler возвращает сообщение 404, когда я получаю доступ к следующим URL-адресам, используя это решение:
Пост Котцака выше и эти статьи были хорошими ссылками.
источник
The IControllerFactory 'aaa.bbb.CustomControllerFactory' did not return a controller for the name '123'.
- есть идеи, почему я получу это?Мое сокращенное решение, которое работает с необработанными областями, контроллерами и действиями:
Создайте представление 404.cshtml.
Создайте базовый класс для ваших контроллеров:
Создайте фабрику пользовательских контроллеров, возвращающую базовый контроллер как запасной вариант:
Добавьте к
Application_Start()
следующей строке:источник
В MVC4 WebAPI 404 может обрабатываться следующим образом,
КУРСЫ APICONTROLLER
ДОМАШНИЙ КОНТРОЛЛЕР
ПОСМОТРЕТЬ
ГЛОБАЛЬНЫЙ
РЕЗУЛЬТАТЫ
источник
Попробуйте NotFoundMVC на nuget. Работает, без настройки.
источник
http://localhost/Views/Shared/NotFound.cshtml
не приводит к пользовательской странице 404.Мое решение, если кто-то найдет его полезным.
В Web.config:
В
Controllers/ErrorController.cs
:Добавьте
PageNotFound.cshtml
вShared
папку, и все.источник
model.RequestedUrl = Request.Url.OriginalString.Contains(url) & Request.Url.OriginalString != url ? Request.Url.OriginalString : url;
а неmodel.RequestedUrl = Request.Url.OriginalString.Contains(url) && Request.Url.OriginalString != url ? Request.Url.OriginalString : url;
(& вместо &&)?Мне кажется, что стандартная
CustomErrors
конфигурация должна просто работать, однако из-за зависимостиServer.Transfer
кажется, что внутренняя реализацияResponseRewrite
не совместима с MVC.Для меня это похоже на явную дыру в функциональности, поэтому я решил повторно реализовать эту функцию с помощью модуля HTTP. Приведенное ниже решение позволяет вам обрабатывать любой код состояния HTTP (включая 404) путем перенаправления на любой действительный маршрут MVC, как вы это обычно делаете.
Это было проверено на следующих платформах;
Льготы
Решение
Применение
Включите это как последний HTTP-модуль в ваш web.config
Для тех из вас, кто обратил внимание, вы заметите, что в режиме Integrated Pipeline он всегда отвечает HTTP 200 из-за способа
Server.TransferRequest
работы. Чтобы вернуть правильный код ошибки, я использую следующий контроллер ошибок.источник
Работа с ошибками в ASP.NET MVC - это просто боль в заднице. Я перепробовал много предложений на этой странице и на других вопросах и сайтах, и ничего не работает хорошо. Одно из предложений заключалось в обработке ошибок в файле web.config внутри system.webserver, но он просто возвращает пустые страницы. .
Моя цель при разработке этого решения заключалась в том, чтобы:
Вот мое решение.
1. Добавьте следующее в раздел system.web
Выше обрабатываются любые URL-адреса, которые не обрабатываются route.config, и необработанные исключения, особенно те, которые встречаются в представлениях. Обратите внимание, что я использовал aspx, а не html . Это так, я могу добавить код ответа на код позади.
2 . Создайте папку с именем Error (или любую другую) в корне вашего проекта и добавьте две веб-формы. Ниже моя страница 404;
И на код позади я установил код ответа
Сделайте то же самое для 500 страниц
3. Для обработки ошибок в контроллерах. Есть много способов сделать это. Это то, что сработало для меня. Все мои контроллеры наследуются от базового контроллера. В базовом контроллере у меня есть следующие методы
4. Добавьте CustomError.cshtml в папку « Общие представления». Ниже мое;
Теперь в вашем контроллере приложения вы можете сделать что-то вроде этого;
Теперь для предостережения . Он не будет обрабатывать статические ошибки файла. Поэтому, если у вас есть маршрут, например example.com/widgets, и пользователь меняет его на example.com/widgets.html , он получит страницу ошибок IIS по умолчанию, поэтому вам придется обрабатывать ошибки уровня IIS другим способом.
источник
Публикация ответа, так как мой комментарий был слишком длинным ...
Это и комментарий, и вопросы к сообщению / ответу единорога:
https://stackoverflow.com/a/7499406/687549
Я предпочитаю этот ответ другим за его простоту и тот факт, что, по-видимому, с некоторыми людьми в Microsoft консультировались. Однако я получил три вопроса, и если на них можно будет ответить, я назову этот ответ святым Граалем всех ответов об ошибках 404/500 на веб-страницах для приложения ASP.NET MVC (x).
@ Pure.Krome
Можете ли вы обновить свой ответ с помощью материалов SEO из комментариев, указанных GWB (в вашем ответе об этом никогда не упоминалось) -
<customErrors mode="On" redirectMode="ResponseRewrite">
и<httpErrors errorMode="Custom" existingResponse="Replace">
?Можете ли вы спросить своих друзей из команды ASP.NET, нормально ли это делать - было бы неплохо получить какое-то подтверждение - может быть, это большое изменение «нет-нет»
redirectMode
иexistingResponse
таким образом уметь играть с SEO ?!Вы можете добавить некоторые разъяснения , окружающий все , что материал (
customErrors redirectMode="ResponseRewrite"
,customErrors redirectMode="ResponseRedirect"
,httpErrors errorMode="Custom" existingResponse="Replace"
, REMOVEcustomErrors
ПОЛНОСТЬЮ , как кто - то предложил) после разговора с друзьями в Microsoft?Как я говорил; было бы здорово, если бы мы могли сделать ваш ответ более полным, поскольку этот вопрос кажется довольно популярным и имеет более 54 000 просмотров.
Обновление : ответ Unicorn делает 302 Найденных и 200 OK и не может быть изменен, чтобы только возвратить 404, используя маршрут. Это должен быть физический файл, который не очень MVC: иш. Так что переходим к другому решению. Жаль, потому что это, казалось, было окончательным ответом MVC: так далеко.
источник
Добавление моего решения, которое почти идентично решению Германа Кана, с небольшой складкой, чтобы оно работало для моего проекта.
Создайте собственный контроллер ошибок:
Затем создайте фабрику пользовательских контроллеров:
Наконец, добавьте переопределение к пользовательскому контроллеру ошибок:
И это все. Нет необходимости в изменениях Web.config.
источник
1) Сделать абстрактный класс Controller.
2) Сделайте наследование от этого абстрактного класса во всех ваших контроллерах
3) И добавьте представление с именем «NotFound» в вашей папке View-Shared.
источник
Я просмотрел большинство решений, опубликованных в этой теме. Хотя этот вопрос может быть старым, он все еще очень применим к новым проектам даже сейчас, поэтому я потратил довольно много времени на чтение ответов, представленных здесь, а также где-либо еще.
Как @Marco указал на различные случаи, в которых может произойти 404, я проверил решение, которое я скомпилировал, по этому списку. В дополнение к его списку требований я также добавил еще один.
Это решение в 2 раза:
Первая часть написана @Guillaume по адресу https://stackoverflow.com/a/27354140/2310818 . Их решение заботится о любых 404, которые были вызваны из-за неверного маршрута, неверного контроллера и недопустимого действия.
Идея состоит в том, чтобы создать WebForm, а затем заставить его вызывать действие NotFound вашего контроллера ошибок MVC. Он делает все это без какого-либо перенаправления, поэтому вы не увидите ни одного 302 в Fiddler. Оригинальный URL также сохраняется, что делает это решение фантастическим!
Вторая часть написана @ Germán по адресу https://stackoverflow.com/a/5536676/2310818 . Их решение заботится о любых 404, возвращенных вашими действиями в форме HttpNotFoundResult () или сгенерировать новый HttpException ()!
Идея состоит в том, чтобы фильтр посмотрел на ответ, а также на исключение, выданное вашими контроллерами MVC, и вызвал соответствующее действие в вашем контроллере ошибок. Опять же, это решение работает без какого-либо перенаправления и оригинальный URL сохраняется!
Как видите, оба этих решения вместе предлагают очень надежный механизм обработки ошибок, и они отвечают всем требованиям, указанным @Marco, а также моим требованиям. Если вы хотите увидеть рабочий образец или демонстрацию этого решения, пожалуйста, оставьте в комментариях, и я был бы рад собрать его вместе.
источник
Я просмотрел все статьи, но у меня ничего не работает: мое требование пользователя должно что-то указывать на вашей странице 404 URL-адреса. Я подумал, что это очень просто. Но вы должны правильно понимать обработку 404:
Я нашел эту статью очень полезной. Должен быть прочитан сразу. Обычная ошибка страницы-Бен Фостер
источник