0

I have spent the whole day trying to implement custom handler for HTTP errors. I am using MVC 5 and IIS 7. There are a lot of good suggestions HERE. Since I need to take care not only for 404 I have tried THIS option.

Ultimately I need to be able to handle all these cases

Should be able to handle all unmatched routes localhost/404_test/test/test/test/test/12/23

Should be able to handle HTTP 500 throw exception from the action

Should be able to handle all html errors for example 400. localhost/404_test/ddsa

Should be able to handle "file extension like url" localhost/404_test/test.cdd

Using the code in the provided link also by updating web.config as shown below I am able to handle all cases except "file extension like url". I am receiving blank page. It looks like IIS is overwriting response. It was the same for unmatched routes before I added

<httpErrors errorMode="Custom" existingResponse="PassThrough" >

Here is the rout map for unmatched cases :

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

Any suggestions how to have this implemented ? I see stackoverflow.com works exactly the way I want to have, but I have no idea how it is implemented.

Web.config

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
     <httpErrors errorMode="Custom" existingResponse="PassThrough" >
      <remove statusCode="404" subStatusCode="-1" />
      <error statusCode="404" subStatusCode="-1" responseMode="ExecuteURL" path="/Error/NotFound" />
      <remove statusCode="500" subStatusCode="-1" />
      <error statusCode="500" subStatusCode="-1" responseMode="ExecuteURL" path="/Error/ServerError" />
    </httpErrors>
  </system.webServer>
Community
  • 1
  • 1
Tamerlane
  • 2,031
  • 3
  • 21
  • 34

1 Answers1

0

This is a solution I have implemented before in an MVC3 app, so it was a while ago. It should handle any invalid URL as well as unhandled exceptions thrown from the application. You should be able to combine this with the code from links above for handling other 40x errors. This code is running on www.carbsandcals.com.

In web.config:

<httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="500" subStatusCode="-1" />
    <remove statusCode="404" subStatusCode="-1" />
    <remove statusCode="400" subStatusCode="-1" />
    <error statusCode="400" prefixLanguageFilePath="" path="/Error/Error/400" responseMode="ExecuteURL" />
    <error statusCode="404" prefixLanguageFilePath="" path="/Error/Error/404" responseMode="ExecuteURL" />
    <error statusCode="500" prefixLanguageFilePath="" path="/Error/Error/500" responseMode="ExecuteURL" />
</httpErrors>

In Global.asax, to handle "view not found" errors thrown by the MVC view engine:

    protected void Application_Error()
    {
        Exception ex = Server.GetLastError();

        bool handleError = false;

        int errorCode = 500;

        if (handleError = (ex is InvalidOperationException && ex.Message.Contains("or its master was not found or no view engine supports the searched locations. The following locations were searched")))
        {
            errorCode = 404;
        }
        else if (handleError = ex is HttpException)
        {
            errorCode = ((HttpException)ex).GetHttpCode();
        }

        if (handleError)
        {
            Server.ClearError();

            Server.TransferRequest("/error/error/" + errorCode);
        }
    }

I'd prefer not to have to test against the error message content but I couldn't find a better way of distinguishing this error from other InvalidOperationExceptions.

Caveat: Although this will handle HttpRequestValidationException errors, the processing of the error page may throw further exceptions of the same type (as the URL is still invalid). I noticed this with Html.RenderPartial and an ASCX as well as interacting with the SiteMap. In this case it may be better to redirect to a simple view or a static page.

The error controller sets the Response.StatusCode so that the correct HTTP code is sent back to the client.

Andrew McLachlan
  • 349
  • 1
  • 14
  • It does not cover all cases ... try '<' inside query string please – Tamerlane Mar 13 '14 at 18:39
  • I had only setup my config to handle 404 and 500 errors. I've expanded the config to include 400 errors. Try www.carbsandcals.com/< now. Note that I have not set up any friendly messages for this error. New config: – Andrew McLachlan Mar 14 '14 at 00:00
  • Thanks for the update Andrew. Actually if you will try www.carbsandcals.com/ – Tamerlane Mar 14 '14 at 03:36
  • Yep, that looks like a condition not covered by the code. It would probably require some generic error handling in Application_Error but I'll have to take a look and see how I can improve it. – Andrew McLachlan Mar 14 '14 at 05:10
  • I've updated my answer to handle requests that throw a HttpRequestValidationException. Still not perfect though (see caveat). – Andrew McLachlan Mar 14 '14 at 12:22