How can I properly handle 404 in ASP.NET MVC?

后端 未结 19 2771
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-21 10:14

I am using RC2

Using URL Routing:

routes.MapRoute(
    \"Error\",
     \"{*url}\",
     new { controller = \"Errors\", action = \"N         


        
19条回答
  •  暖寄归人
    2020-11-21 10:38

    I've investigated A LOT on how to properly manage 404s in MVC (specifically MVC3), and this, IMHO is the best solution I've come up with:

    In global.asax:

    public class MvcApplication : HttpApplication
    {
        protected void Application_EndRequest()
        {
            if (Context.Response.StatusCode == 404)
            {
                Response.Clear();
    
                var rd = new RouteData();
                rd.DataTokens["area"] = "AreaName"; // In case controller is in another area
                rd.Values["controller"] = "Errors";
                rd.Values["action"] = "NotFound";
    
                IController c = new ErrorsController();
                c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
            }
        }
    }
    

    ErrorsController:

    public sealed class ErrorsController : Controller
    {
        public ActionResult NotFound()
        {
            ActionResult result;
    
            object model = Request.Url.PathAndQuery;
    
            if (!Request.IsAjaxRequest())
                result = View(model);
            else
                result = PartialView("_NotFound", model);
    
            return result;
        }
    }
    

    (Optional)

    Explanation:

    AFAIK, there are 6 different cases that an ASP.NET MVC3 apps can generate 404s.

    (Automatically generated by ASP.NET Framework:)

    (1) An URL does not find a match in the route table.

    (Automatically generated by ASP.NET MVC Framework:)

    (2) An URL finds a match in the route table, but specifies a non-existent controller.

    (3) An URL finds a match in the route table, but specifies a non-existant action.

    (Manually generated:)

    (4) An action returns an HttpNotFoundResult by using the method HttpNotFound().

    (5) An action throws an HttpException with the status code 404.

    (6) An actions manually modifies the Response.StatusCode property to 404.

    Normally, you want to accomplish 3 objectives:

    (1) Show a custom 404 error page to the user.

    (2) Maintain the 404 status code on the client response (specially important for SEO).

    (3) Send the response directly, without involving a 302 redirection.

    There are various ways to try to accomplish this:

    (1)

    
        
            
        
    
    

    Problems with this solution:

    1. Does not comply with objective (1) in cases (1), (4), (6).
    2. Does not comply with objective (2) automatically. It must be programmed manually.
    3. Does not comply with objective (3).

    (2)

    
        
            
            
        
    
    

    Problems with this solution:

    1. Only works on IIS 7+.
    2. Does not comply with objective (1) in cases (2), (3), (5).
    3. Does not comply with objective (2) automatically. It must be programmed manually.

    (3)

    
        
            
            
        
    
    

    Problems with this solution:

    1. Only works on IIS 7+.
    2. Does not comply with objective (2) automatically. It must be programmed manually.
    3. It obscures application level http exceptions. E.g. can't use customErrors section, System.Web.Mvc.HandleErrorAttribute, etc. It can't only show generic error pages.

    (4)

    
        
            
        
    
    

    and

    
        
            
            
        
    
    

    Problems with this solution:

    1. Only works on IIS 7+.
    2. Does not comply with objective (2) automatically. It must be programmed manually.
    3. Does not comply with objective (3) in cases (2), (3), (5).

    People that have troubled with this before even tried to create their own libraries (see http://aboutcode.net/2011/02/26/handling-not-found-with-asp-net-mvc3.html). But the previous solution seems to cover all the cases without the complexity of using an external library.

提交回复
热议问题