ASP.NET MVC 4 404错误处理未触发

时间:2014-08-08 12:33:10

标签: asp.net-mvc asp.net-mvc-4

首先,我不是轻易发布的。我刚刚花了近半天的时间试图解决这个问题。

我正在笔记本电脑上使用Visual Studio 2012开发ASP.NET MVC网站。我已经使用this approach将此代码添加到我的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();
    }

我有一个在Razor标记中产生错误的视图:

@{
            // trigger an error
            int i =1/0; 
        }

当我浏览到这个视图时,它会触发一个错误,将我带到控制器Error,action Index,这段代码显示了一个合适的视图:

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

到目前为止,这么好。我的问题是 - 如何以相同的方式处理404?所以如果我去一个不存在的页面,我得到:

enter image description here

我尝试过的事情:

  • CustomErrors的每种可能安排 - web.config中的开/关
  • 调试global.asax以检查它是否在应用程序启动时运行
  • 很多其他事情,我敢肯定,我现在已经忘记了!

Visual Studio使用的Web服务器是IIS 8 Express,如果有任何帮助的话。

3 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点。

最简单的方法

下载并安装此nuget - NotFoundMvc并对此blog post进行阅读。

或者在SO上查看这个美丽的answer,或者从Real world error hadnling in ASP.NET MVC RC2获取。但由于源站点的当前状态处于可怕的设计状态,我将在下面重新发布代码。

目标:

捕获服务器上发生的每个错误都包括像404这样的HttpExeptions(找不到页面)。

为某些错误选择特定视图(错误模板)的能力以及指定的通用视图/行为。

场景1: anonymus用户输入了错误的网址。 操作: 显示用户友好的消息,如:“OOPS,页面丢失...回到家” 将错误记录到服务器上的.log文件中。 发送电子邮件给管理员。

Senario 2: 与场景1相同,但有一点不同:用户是匿名者,但他的IP来自我们公司的办公室。 操作: 显示详细错误。

让我们看一些代码:

protected void Application_Error(object sender,EventArgs e){

Exception exception = Server.GetLastError();

// Log the exception.
ILogger logger = Container.Resolve < ILogger > ();
logger.Error(exception);

Response.Clear();


HttpException httpException = exception as HttpException;
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");

if (httpException == null) {
    routeData.Values.Add("action", "Index");
} else //It's an Http Exception, Let's handle it.
{

    switch (httpException.GetHttpCode()) {
        case 404:
            // Page not found.
            routeData.Values.Add("action", "HttpError404");
            break;
        case 500:
            // Server error.
            routeData.Values.Add("action", "HttpError500");
            break;
            // Here you can handle Views to other error codes.
            // I choose a General error template  
        default:
            routeData.Values.Add("action", "General");
            break;
    }
}

// Pass exception details to the target error View.
routeData.Values.Add("error", exception);

// Clear the error on server.
Server.ClearError();

// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));

}

将此方法添加到Global.asax:

创建了一个名为ErrorController的新控制器:

你可以为另一个eception类型指定一些更多的行为,我为了错误而强调了一个视图:404,500。

public ActionResult HttpError404(string error) {
    ViewData["Title"] = "Sorry, an error occurred while processing your request. (404)";
    ViewData["Description"] = error;
    return View("Index");
}

public ActionResult HttpError500(string error) {
    ViewData["Title"] = "Sorry, an error occurred while processing your request. (500)";
    ViewData["Description"] = error;
    return View("Index");
}


public ActionResult General(string error) {
    ViewData["Title"] = "Sorry, an error occurred while processing your request.";
    ViewData["Description"] = error;
    return View("Index");
}

答案 1 :(得分:0)

您需要在MVC的路由引擎中捕获它。添加如下路线:

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

然后在ErrorController添加此操作:

public ActionResult Http404()
{
    Response.StatusCode = (int)HttpStatusCode.NotFound;
    return View();
}

答案 2 :(得分:0)

Yasser的链接让我得到了一个似乎有用的答案。在web.config文件 部分中,添加:

   <httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/PageNotFound" />
 </httpErrors>

然后,您可以为此路径创建路由器和控制器,这一切似乎都有效。它真的那么简单吗?