且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在MVC5中配置和代码中处理404错误?

更新时间:2023-02-25 08:16:04

web.config



关闭自定义system.web中的错误

 < system.web> 
< customErrors mode =Off/>
< /system.web>

在system.webServer中配置http错误

 &LT; system.webServer&GT; 
< httpErrors errorMode =CustomexistingResponse =Auto>
< clear />
< error statusCode =404responseMode =ExecuteURLpath =/ NotFound/>
< error statusCode =500responseMode =ExecuteURLpath =/ Error/>
< / httpErrors>
< /system.webServer>

创建简单的错误控制器来处理这些请求 ErrorContoller.cs

  [AllowAnonymous] 
public class ErrorController:Controller {
// GET:错误
public ActionResult NotFound (){
var statusCode =(int)System.Net.HttpStatusCode.NotFound;
Response.StatusCode = statusCode;
Response.TrySkipIisCustomErrors = true;
HttpContext.Response.StatusCode = statusCode;
HttpContext.Response.TrySkipIisCustomErrors = true;
return View();
}

public ActionResult Error(){
Response.StatusCode =(int)System.Net.HttpStatusCode.InternalServerError;
Response.TrySkipIisCustomErrors = true;
return View();
}
}

配置路由 RouteConfig.cs

  public static void RegisterRoutes(RouteCollection routes){

//...other routes

routes.MapRoute(
name:404-NotFound,
url:NotFound,
defaults:new {controller =Error,action = NotFound}
);

routes.MapRoute(
name:500-Error,
url:Error,
defaults:new {controller =Error,action = 错误}
);

//..其他路由

//我也把所有映射作为最后一个路由

//捕获所有的InValid(NotFound)路由
routes.MapRoute(
name:NotFound,
url:{* url},
defaults:new {controller =Error,action =NotFound }
);
}

最后确保你有控制器操作的视图

 视图/共享/ NotFound.cshtml 
视图/共享/ Error.cshtml
pre>

如果您想处理任何其他错误,您可以按照该模式进行添加,并根据需要添加。这将避免重定向并维护原始的http错误状态。


I have implemented exception handling as mentioned in below link

How to pass error message to error view in MVC 5?

It is working fine. But I have requirement to handle 404 Error.

How can I do that?

if I use below code,

<customErrors mode="On">
  <error statusCode="404" redirect="/Home/Error"></error>
</customErrors>

it works well when any 404 error occurs. But in case any other exception occurs then my error.cshtml call twice and show same exception two times.

web.config

Turn off custom errors in system.web

<system.web>
    <customErrors mode="Off" />
</system.web>

configure http errors in system.webServer

<system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Auto">
      <clear />
      <error statusCode="404" responseMode="ExecuteURL" path="/NotFound" />
      <error statusCode="500" responseMode="ExecuteURL" path="/Error" />
    </httpErrors>
</system.webServer>

Create simple error controller to handle those requests ErrorContoller.cs

[AllowAnonymous]
public class ErrorController : Controller {
    // GET: Error
    public ActionResult NotFound() {
        var statusCode = (int)System.Net.HttpStatusCode.NotFound;
        Response.StatusCode = statusCode;
        Response.TrySkipIisCustomErrors = true;
        HttpContext.Response.StatusCode = statusCode;
        HttpContext.Response.TrySkipIisCustomErrors = true;
        return View();
    }

    public ActionResult Error() {
        Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
        Response.TrySkipIisCustomErrors = true;
        return View();
    }
}

configure routes RouteConfig.cs

public static void RegisterRoutes(RouteCollection routes) {

    //...other routes 

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

    routes.MapRoute(
        name: "500-Error",
        url: "Error",
        defaults: new { controller = "Error", action = "Error" }
    );

    //..other routes

    //I also put a catch all mapping as last route

    //Catch All InValid (NotFound) Routes
    routes.MapRoute(
        name: "NotFound",
        url: "{*url}",
        defaults: new { controller = "Error", action = "NotFound" }
    );
}

And finally make sure you have views for the controller actions

Views/Shared/NotFound.cshtml
Views/Shared/Error.cshtml

If there are any additional error you want to handle you can follow that pattern and add as needed. This will avoid redirects and maintain the original http error status that was raised.