102

Я пытаюсь создать пользовательскую страницу ошибки HTTP 404, когда кто-то печатает URL-адрес , который не вызывает действительное действие или контроллер в ASP.NET MVC, а не его отображая общую ошибку ASP.NET «Ресурс не найден».Маршрутизация для пользовательской ASP.NET MVC 404 Страница ошибки

Я не хочу использовать web.config для обработки этого.

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

Обновление: Я пробовал ответить, однако я до сих пор получаю уродливое сообщение «Ресурс не найден».

Другое обновление: Хорошо, видимо, что-то изменилось в RC1. Я даже пробовал специально захватить 404 на HttpException, и он по-прежнему просто дает мне страницу «Ресурс не найден».

Я даже использовал функцию ресурса MvcContrib и ничего - ту же проблему. Есть идеи?

+0

дубликата http://stackoverflow.com/questions/310580/how-can -i-make-a-catch-all-route-to-handle-404-page-not-found-queries-for-asp-n –

+0

@Peter Это решение, которое я добавил, наряду с переопределением HandleUnknownAction, чтобы показать страница не найдена, когда действие не существует, а затем встроенное ASP.net пользовательский обработчик ошибок, чтобы обрабатывать все остальное, что пользователи могут вводить. – dswatik

+0

@pete Это также работает http://stackoverflow.com/questions/619895/how-can-i-properly-handle-404s-in- asp-net-mvc/620559 # 620559 – dswatik

ответ

8

Просто добавьте уловить весь маршрут в конце таблицы маршрутов и отобразите любую страницу, которую вы хотите с ней.

См: How can i make a catch all route to handle '404 page not found' queries for ASP.NET MVC?

+0

Я пробовал это, однако, я все еще получаю уродливое сообщение об исходном ресурсе по умолчанию ASP.NET. – dswatik

+3

не найти окончательное (и гибкое !!) решение этой проблемы ни в этом андре er или по предоставленной ссылке. – Peter

+4

Я тоже ... это похоже на хриплый ответ. Я ищу больше для того, чтобы заставить customErrors вести себя так, как в WebForms. Есть идеи? –

39

Я получил свою обработку ошибок, чтобы работать, создавая ErrorController, которая возвращает точку в этой статье. Мне также пришлось добавить «Поймать все» к маршруту в global.asax.

Я не вижу, как он попадет на любую из этих страниц ошибок, если это не в Web.config ..? Мой Web.config должен указать:

customErrors mode="On" defaultRedirect="~/Error/Unknown" 

, а затем я также добавил:

error statusCode="404" redirect="~/Error/NotFound" 
+2

Спасибо, что помогли мне, через 2 года! Что вы делаете, если только хотите создать ошибку 404, и ничего больше? –

+0

@Shaul еще год спустя ... не устанавливайте defaultRedirect, полностью исключайте атрибут. – voiddog

0

У меня была та же проблема, то, что вам нужно сделать, это, вместо того, чтобы добавлять атрибут CustomErrors в файл web.config в папке «Представления», вы должны добавить его в файл web.config в корневую папку ваших проектов.

95

Я попытался включить пользовательские ошибки на рабочем сервере в течение 3 часов, кажется, нашел окончательное решение, как сделать это в ASP.NET MVC без каких-либо маршрутов.

Чтобы включить пользовательские ошибки в приложении ASP.NET MVC нам нужно (IIS 7+):

  1. Настройка пользовательских страниц в веб-конфигурации под system.web разделе:

    <customErrors mode="RemoteOnly" defaultRedirect="~/error"> 
        <error statusCode="404" redirect="~/error/Error404" /> 
        <error statusCode="500" redirect="~/error" /> 
    </customErrors> 
    

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

  2. Установите волшебный параметр отклика и ответа код состояния (в модуле обработки ошибок или ошибок атрибута ручки)

    HttpContext.Current.Response.StatusCode = 500; 
        HttpContext.Current.Response.TrySkipIisCustomErrors = true; 
    
  3. Установите другую волшебную установку в веб-конфигурации под system.webServer разделе:

    <httpErrors errorMode="Detailed" /> 
    

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

+7

Это еще не идеальное решение. Он не получает правильные коды ответа HTTP. Использование 'customErrors' приводит к перенаправлению 302 только для загрузки страницы с ошибкой. –

+0

@ Ek0nomik Я никогда не видел идеальных решений :) –

+2

@JustinHelgerson Я настраиваю ErrorController для каждого кода состояния и устанавливаю коды ответов внутри этих действий, и он устанавливает коды ответов в порядке. Я тестировал с помощью Fiddler и 404 кодов состояния 404 и страницы с 500 ошибками отвечают на 500. И в обоих случаях мои пользовательские представления об ошибках подаются до –

16

Попробуйте это в web.config, чтобы заменить страницы ошибок IIS. Это лучшее решение, которое я предполагаю, и оно также отправляет правильный код состояния.

<system.webServer> 
    <httpErrors errorMode="Custom" existingResponse="Replace"> 
    <remove statusCode="404" subStatusCode="-1" /> 
    <remove statusCode="500" subStatusCode="-1" /> 
    <error statusCode="404" path="Error404.html" responseMode="File" /> 
    <error statusCode="500" path="Error.html" responseMode="File" /> 
    </httpErrors> 
</system.webServer> 

Более подробная информация от Tipila - Use Custom Error Pages ASP.NET MVC

+1

+1. Это единственное, что, казалось, работало для меня на MVC5 с несколькими областями. – hawkke

+0

Это самое простое решение. Однако вы не можете использовать синтаксис бритвы на странице с ошибкой. – highace

26

Source

NotFoundMVC - Предоставляет удобную страницу 404 всякий раз, когда контроллер, действие или маршрут не найден в приложении ASP.NET MVC3. Вид, называемый NotFound, отображается вместо страницы с ошибкой ASP.NET по умолчанию.

Вы можете добавить этот плагин с помощью NuGet с помощью: Install-Package NotFoundMvc

NotFoundMvc автоматически устанавливает себя во время веб-приложений пуска. Он обрабатывает все различные способы, с помощью которых ASP.NET MVC обычно вызывается 404 HttpException. Это включает в себя отсутствующий контроллер, действие и маршрут.

Шаг за шагом руководство по установке:

1 - правой кнопкой мыши на проекте и выберите Управление NuGet пакеты ...

2 - Поиск NotFoundMvc и установить его. enter image description here

3 - Как только установка будет завершена, в проект будут добавлены два файла. Как показано на скриншотах ниже.

enter image description here

4 - Откройте новый добавленный NotFound.cshtml подарок в Views/Shared и изменить его по вашему желанию. Теперь запустите приложение и введите неправильный URL-адрес, и вас встретит дружественная страница 404. не

enter image description here

Нет больше, пользователи будут получать ошибки сообщений как Server Error in '/' Application. The resource cannot be found.

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

P.S: Престижность Andrew Davey для создания такого удивительного плагина.

+0

Предоставляет ли это надлежащие коды ответа HTTP? – niico

+0

@niico От взгляда на исходный код кажется, что код ответа равен 404, так что да. –

13

Этому решению не нужны изменения файла web.config или маршруты для всех маршрутов.

Во-первых, создайте такой контроллер;

public class ErrorController : Controller 
{ 
    public ActionResult Index() 
    { 
     ViewBag.Title = "Regular Error"; 
     return View(); 
    } 

    public ActionResult NotFound404() 
    { 
     ViewBag.Title = "Error 404 - File not Found"; 
     return View("Index"); 
    } 
} 

Затем создайте представление в разделе «Views/Error/Index.cshtml» as;

@{ 
     Layout = "~/Views/Shared/_Layout.cshtml"; 
    }      
    <p>We're sorry, page you're looking for is, sadly, not here.</p> 

Затем добавьте следующий код в глобальный файл asax, как показано ниже:

protected void Application_Error(object sender, EventArgs e) 
{ 
     // Do whatever you want to do with the error 

     //Show the custom error page... 
     Server.ClearError(); 
     var routeData = new RouteData(); 
     routeData.Values["controller"] = "Error"; 

     if ((Context.Server.GetLastError() is HttpException) && ((Context.Server.GetLastError() as HttpException).GetHttpCode() != 404)) 
     { 
      routeData.Values["action"] = "Index"; 
     } 
     else 
     { 
      // Handle 404 error and response code 
      Response.StatusCode = 404; 
      routeData.Values["action"] = "NotFound404"; 
     } 
     Response.TrySkipIisCustomErrors = true; // If you are using IIS7, have this line 
     IController errorsController = new ErrorController(); 
     HttpContextWrapper wrapper = new HttpContextWrapper(Context); 
     var rc = new System.Web.Routing.RequestContext(wrapper, routeData); 
     errorsController.Execute(rc); 

     Response.End(); 
} 

Если вы все еще получаете страницу ошибки IIS после того, как сделать это, убедитесь, что следующие разделы закомментировано (или пустой) в файле веб-конфигурации:

<system.web> 
    <customErrors mode="Off" /> 
</system.web> 
<system.webServer> 
    <httpErrors>  
    </httpErrors> 
</system.webServer> 
+0

Я не думаю, что этот подход будет работать во всех случаях, поскольку 404 часто перехватывается веб-сервером и поэтому никогда не обрабатывается на уровне приложения. –

+0

Я хочу добавить, что если вы пойдете с этим подходом, я бы рекомендовал добавить 'Response.End();' в конец вашего обработчика Application_Error. Без этого для данного сеанса запускается только первое возникновение ошибки, что является проблемой, если у вас есть, например, настраиваемый журнал ошибок в обработчике Application_Error. – Keith

4

Если вы работаете в MVC 4, вы можете смотреть this решение, он работал на меня.

Добавьте следующий метод Application_Error к моему Global.asax:

protected void Application_Error(object sender, EventArgs e) 
{ 
    Exception exception = Server.GetLastError(); 
    Server.ClearError(); 

    RouteData routeData = new RouteData(); 
    routeData.Values.Add("controller", "Error"); 
    routeData.Values.Add("action", "Index"); 
    routeData.Values.Add("exception", exception); 

    if (exception.GetType() == typeof(HttpException)) 
    { 
     routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode()); 
    } 
    else 
    { 
     routeData.Values.Add("statusCode", 500); 
    } 

    IController controller = new ErrorController(); 
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); 
    Response.End(); 

Сам контроллер очень прост:

public class ErrorController : Controller 
{ 
    public ActionResult Index(int statusCode, Exception exception) 
    { 
     Response.StatusCode = statusCode; 
     return View(); 
    } 
} 

Проверьте полный исходный код Mvc4CustomErrorPage at GitHub.

0

Настоящий ответ позволяет полностью настроить страницу ошибок в одном месте. Не нужно изменять web.config или создавать отдельный код.

Работы также в MVC 5.

Добавьте этот код в контроллер:

 if (bad) { 
      Response.Clear(); 
      Response.TrySkipIisCustomErrors = true; 
      Response.Write(product + I(" Toodet pole")); 
      Response.StatusCode = (int)HttpStatusCode.NotFound; 
      //Response.ContentType = "text/html; charset=utf-8"; 
      Response.End(); 
      return null; 
     } 

на основе http://www.eidias.com/blog/2014/7/2/mvc-custom-error-pages