120

当有人在 ASP.NET MVC 中键入的 URL 未调用有效操作或控制器时,我试图创建一个自定义 HTTP 404 错误页面,而不是显示通用的“找不到资源”ASP.NET 错误。

我不想使用 web.config 来处理这个问题。

有没有什么我可以做的路由魔法来捕捉任何无效的 URL?

更新:我尝试了给出的答案,但是我仍然收到丑陋的“找不到资源”消息。

另一个更新:好的,显然 RC1 发生了一些变化。我什至尝试专门在 an 上捕获 404 HttpException,但它仍然只是给我“找不到资源”页面。

我什至使用了 MvcContrib 的资源功能,但什么也没有——同样的问题。有任何想法吗?

4

10 回答 10

110

我尝试在生产服务器上启用自定义错误 3 小时,似乎我找到了最终解决方案,如何在没有任何路由的 ASP.NET MVC 中执行此操作。

要在 ASP.NET MVC 应用程序中启用自定义错误,我们需要(IIS 7+):

  1. 在 web configsystem.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. 在 web config 部分下设置另一个魔术设置system.webServer

    <httpErrors errorMode="Detailed" />
    

这是我发现的最后一件事,之后我可以在生产服务器上看到自定义错误。

于 2011-09-16T08:58:14.337 回答
41

我通过创建返回本文中的视图的 ErrorController 使我的错误处理工作。我还必须将“Catch All”添加到 global.asax 中的路线。

如果它不在 Web.config.. 中,我看不到它如何到达这些错误页面中的任何一个?我的 Web.config 必须指定:

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

然后我还补充说:

error statusCode="404" redirect="~/Error/NotFound"
于 2009-08-17T16:00:29.883 回答
28

来源

NotFoundMVC - 只要在 ASP.NET MVC3 应用程序中找不到控制器、操作或路由,就会提供用户友好的 404 页面。将呈现一个名为 NotFound 的视图,而不是默认的 ASP.NET 错误页面。

您可以使用以下方法通过 nuget 添加此插件:Install-Package NotFoundMvc

NotFoundMvc 在 Web 应用程序启动期间自动安装。它处理 404 HttpException 通常由 ASP.NET MVC 抛出的所有不同方式。这包括缺少的控制器、动作和路由。

分步安装指南:

1 - 右键单击​​您的项目并选择管理 Nuget 包...

2 - 搜索NotFoundMvc并安装它。 在此处输入图像描述

3 - 安装完成后,两个文件将添加到您的项目中。如下图所示。

在此处输入图像描述

4 - 打开 Views/Shared 中新添加的 NotFound.cshtml 并随意修改。现在运行应用程序并输入错误的 url,您将看到一个用户友好的 404 页面。

在此处输入图像描述

不再,用户会收到类似的错误消息Server Error in '/' Application. The resource cannot be found.

希望这可以帮助 :)

PS:感谢Andrew Davey制作了这么棒的插件。

于 2012-11-03T12:07:57.367 回答
20

在 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 提供的更多信息- 使用自定义错误页面 ASP.NET MVC

于 2012-03-15T06:20:26.173 回答
15

此解决方案不需要更改 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”下创建视图为;

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

然后在 Global 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 错误页面,请确保在 Web 配置文件中将以下部分注释掉(或为空):

<system.web>
   <customErrors mode="Off" />
</system.web>
<system.webServer>   
   <httpErrors>     
   </httpErrors>
</system.webServer>
于 2013-03-19T21:58:42.860 回答
11

只需在路线表的末尾添加捕获所有路线并显示您想要的任何页面。

请参阅:我如何制作一条捕获所有路由来处理 ASP.NET MVC 的“404 页面未找到”查询?

于 2009-02-16T17:40:51.630 回答
6

如果你在 MVC 4 中工作,你可以观看这个解决方案,它对我有用。

将以下 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();
    }
}

在 GitHub 上查看 Mvc4CustomErrorPage的完整源代码。

于 2015-05-25T08:30:58.610 回答
0

我有同样的问题,你必须做的是,而不是在你的 Views 文件夹的 web.config 文件中添加 customErrors 属性,你必须将它添加到你的项目根文件夹的 web.config 文件中

于 2009-12-27T15:35:27.837 回答
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

于 2016-07-22T16:13:23.400 回答
0

我会讲一些具体的案例,

如果您在 HomeController 中使用“PageNotFound 方法”,如下所示

[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

这行不通。但是您必须清除如下所示的路线标签,

//[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

如果您将其更改为 web.config 中的方法名称,则它可以工作。 但是不要忘记在 web.config 中执行如下代码

<customErrors mode="On">
  <error statusCode="404" redirect="~/PageNotFound" /> 
 *// it is not "~/404" because it is not accepted url in Route Tag like [Route("404")]*
</customErrors>
于 2019-03-11T16:00:00.610 回答