I\'ve been struggling all day to implement error handling in my ASP.NET MVC 2 app. I\'ve looked at a variety of techniques, but none work properly. I\'m using MVC2 and .NET
Here's one technique you could use. Define an ErrorsController
which will serve the error pages:
public class ErrorsController : Controller
{
public ActionResult Http404()
{
Response.StatusCode = 404;
return Content("404", "text/plain");
}
public ActionResult Http500()
{
Response.StatusCode = 500;
return Content("500", "text/plain");
}
public ActionResult Http403()
{
Response.StatusCode = 403;
return Content("403", "text/plain");
}
}
and then in Global.asax
you could subscribe for the Application_Error
event where you could log the exception and execute the corresponding action of the ErrorsController
:
protected void Application_Error(object sender, EventArgs e)
{
var app = (MvcApplication)sender;
var context = app.Context;
var ex = app.Server.GetLastError();
context.Response.Clear();
context.ClearError();
var httpException = ex as HttpException;
var routeData = new RouteData();
routeData.Values["controller"] = "errors";
routeData.Values["exception"] = ex;
routeData.Values["action"] = "http500";
if (httpException != null)
{
switch (httpException.GetHttpCode())
{
case 404:
routeData.Values["action"] = "http404";
break;
case 403:
routeData.Values["action"] = "http403";
break;
case 500:
routeData.Values["action"] = "http500";
break;
}
}
IController controller = new ErrorsController();
controller.Execute(new RequestContext(new HttpContextWrapper(context), routeData));
}
And now all that's left is to start throwing proper exceptions:
public class HomeController : Controller
{
public ActionResult Index()
{
throw new HttpException(404, "NotFound");
}
}
For HTTP 404 errors (without redirects) take a look at my blog post on the subject. This might give you some good ideas:
http://hectorcorrea.com/blog/returning-http-404-in-asp-net-mvc/16
This doesn't answer your question, but it is important to note that HTTP status 500 indicates that something went wrong on the server, so your example:
POST /User/New/new-user-name-too-long-for-db-column-constraint
Is not valid grounds to throw a 500, its a data validation issue and should be handled by MVC data annotations or a jQuery validation framework or etc. Just showing an error message next to the TextBox saying "User Name too long" is much better.
This is a very old question. but I thought It's worth it if I introduce you to a much much cleaner way to handle Http Exceptions that I saw in dear "Jesse Webb's answer".
The solution is to use the httpErrors
element of the system.webServer
section:
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL" />
<error statusCode="500" path="/Error" responseMode="ExecuteURL" />
</httpErrors>
You also can log all exceptions in this way. "Read the "Jesse Webb's answer"".
This really feels much cleaner and also works as well as every other solution (without redirect).
Note: This only works work in IIS 7 and and newer. (Because of the httpErrors
element which was recently added.