Reputation: 2103
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>
Upvotes: 0
Views: 3866
Reputation: 349
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.
Upvotes: 0