Question

I'm trying to properly handle and return a 404 for this URL: http://localhost:2867/dd./xml (notice the dot before the slash)

In my current implementation I get 4 exceptions/errors in Application_Error. The first exception returned by Server.GetLastError() is System.Web.HttpException while the next three are null.

I made a bare minimum implementation to reproduce this issue. Here's the code in global.asax.cs:

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

  var routeData = new RouteData();
  routeData.Values.Add("controller", "Error");
  routeData.Values.Add("action", "Generic");
  routeData.Values.Add("area", "");

  IController errorController = new ErrorController();
  // this line throws System.Web.HttpException is a view is returned from ErrorController
  errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}

The error controller looks like this:

public class ErrorController : Controller
{
  public ActionResult Generic()
  {
    Response.TrySkipIisCustomErrors = true;
    Response.StatusCode = (int)HttpStatusCode.NotFound;

    return View();
    // returning content rather than a View doesn't fire 'System.Web.HttpException' in Application_Error
    //return Content("Some error!");
  }
}

There are two issues. One is that for the given URL instead of one error in Application_Error I get 3 or 4, and the other is that when returning a view from the ErrorController an exception is thrown on the Execute call line in Application_Start. If a Content("something") is returned instead this internal (to MVC I assume) exception is not triggered.

In order to see the problem you have to be in debug mode and use the development server. When using IIS or IIS Express the error is not caught for some reason. Also, every now and then these errors go away. To get it back to the beginning you have to clean the solution.

If you'd like to play with it here's the bare minimum solution: http://dl.dropbox.com/u/16605600/InvalidUrl.zip

Thank you for your help!

Was it helpful?

Solution

If you're using IIS7+ putting this in the web.config works:

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

(Answer from How can I properly handle 404 in ASP.NET MVC?)

Would still be nice to know what is going on in the Application_Error.

OTHER TIPS

You can handle a 404 by changing the customeErrors section in the web.config
There is also a redirectMode attribute which you can use to control the nature of the error page redirection (and avoid the 302) (Read here)

<configuration>
  ...
  <system.web>
    <customErrors mode="RemoteOnly" 
                  redirectMode="ResponseRewrite" 
                  defaultRedirect="/ErrorPages/Oops.aspx">
      <error statusCode="404" redirect="/ErrorPages/404.aspx" />
    </customErrors>
...

http://www.asp.net/hosting/tutorials/displaying-a-custom-error-page-cs

In ASP.net MVC, there is a method you can override to catch all exceptions thrown in a controller. Just override Controller.OnException(...) and you can do custom error handling in there as well. If all of your controllers inherit from a common base controller class, you can put the error handling there.

http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.onexception.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top