9
votes

For some reason, when entering a dud URL to a file/directory/controller that does not exist, the following error is thrown:

System.Web.HttpException The controller for path '' was not found or does not implement IController System.Web.Mvc.IController > GetControllerInstance(System.Web.Routing.RequestContext, System.Type)

IIS then follows the regular error handling and shows the page appropriate for a 500 Internal Server Error. A 404 Not Found error handling logic should be followed. Another web application I am testing on DOES NOT throw this HttpException when it can't find a route, and returns 404 normally. So what triggeres this HttpException?

Why and how to follow a 404 route for this type of error instead of a 500? Below is the configuration of the error handling. No other code is handling errors. So why is the 500 error always shown. It's as if the default handling handles the 'can't find controller' exception as an error when in fact it's a not-found.

<system.webServer>
 <httpErrors errorMode="Custom" existingResponse="Replace" defaultPath="/StaticErrors/Default.html" defaultResponseMode="ExecuteURL">
   <clear />
   <error statusCode="404" path="/mvcError/Http404" responseMode="ExecuteURL" />    
   <error statusCode="500" path="/mvcError/Http500" responseMode="ExecuteURL" />     
 </httpErrors>
</system.webServer>
<system.web>
 <customErrors defaultRedirect="/StaticErrors/Default.html" mode="On" redirectMode="ResponseRewrite">
   <error redirect="/mvcError/Http404" statusCode="404" />          
   <error redirect="/mvcError/Http500" statusCode="500" />         
 </customErrors>
</system.web>

Failed Request Trace shows this. Basically since no route is round, the HttpException is thrown, and the 500 route handling kicks in, instead of a 404. I'm not doing anything to overide any normal default behaviour. The HandleErrorAttribute is not being added either to the MVC filters.

enter image description here

2
Perhaps give us an example of a URL that produces the undesirable message.Andrew Shepherd
Have you tried [This][1] [1]: stackoverflow.com/questions/5385714/…Amol
Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it. You should provide all your route maps.Erik Philips
@ErikPhilips The question does include the desired behavior. This isn't a why the code doesn't work query. It's a how does one reflect a route not found exception as a HTTP 404 instead of a HTTP 500... The routes are irrelevant, as I'm not hitting a route, hence the exception. This is simply using a new project in Visual Studio and the web.config changed to above.simbolo
The only way to change the error code is to catch the exception and change the http status code in code. The web.config can't change http status codes to other status codes.Erik Philips

2 Answers

1
votes

You should add a filter controller to override some IIS custom error.

public class mvcErrorController : Controller
   {
    public ActionResult Http404()
    {
    Response.StatusCode = 404;
    Response.TrySkipIisCustomErrors = true; 
    return View();
   }
}
1
votes

You need to remove the

redirectMode="ResponseRewrite"

Option from you customErrors tag. Unfortunately, this does mean you will have a 302 before your 404, but it will fix your issue.

Alternatively, use ASPX pages for your error pages:

<customErrors defaultRedirect="/StaticErrors/Default.html" mode="On" redirectMode="ResponseRewrite">
   <error redirect="/StaticErrors/Http404.aspx" statusCode="404" />          
   <error redirect="/StaticErrors/Http500.aspx" statusCode="500" />         
</customErrors>

There is previous discussion on this issue on SO here