views:

15209

answers:

4

How do I go about the [HandleError] filter in asp.net MVC Preview 5?
I set the customErrors in my Web.config file

<customErrors mode="On" defaultRedirect="Error.aspx">
  <error statusCode="403" redirect="NoAccess.htm"/>
  <error statusCode="404" redirect="FileNotFound.htm"/>
</customErrors>

and put [HandleError] above my Controller Class like this:

[HandleError]
public class DSWebsiteController: Controller
{
    [snip]
    public ActionResult CrashTest()
    {
        throw new Exception("Oh Noes!");
    }
}

Then I let my controllers inherit from this class and call CrashTest() on them. Visual studio halts at the error and after pressing f5 to continue, I get rerouted to Error.aspx?aspxerrorpath=/sxi.mvc/CrashTest (where sxi is the name of the used controller. Off course the path cannot be found and I get "Server Error in '/' Application." 404.

This site was ported from preview 3 to 5. Everything runs (wasn't that much work to port) except the error handling. When I create a complete new project the error handling seems to work.

Ideas?

--Note--
Since this question has over 3K views now, I thought it would be beneficial to put in what I'm currently (ASP.NET MVC 1.0) using. In the mvc contrib project there is a brilliant attribute called "RescueAttribute" You should probably check it out too ;)

+3  A: 

You are missing Error.aspx :) In preview 5, this is located in your Views/Shared folder. Just copy it over from a new Preview 5 project.

Ricky
Thanks for the reply, but I already copied the Error.aspx page.Could indeed have been something I would normally forget, but not this time. :P
borisCallens
+57  A: 
[HandleError]

When you provide only the HandleError attribute to your class (or to your action method for that matter), then when an unhandled exception occurs MVC will look for a corresponding View named "Error" first in the Controller's View folder. If it can't find it there then it will proceed to look in the Shared View folder (which should have an Error.aspx file in it by default)

[HandleError(ExceptionType = typeof(SqlException), View = "DatabaseError")]]
[HandleError(ExceptionType = typeof(NullReferenceException), View = "LameErrorHandling")]]

You can also stack up additional attributes with specific information about the type of exception you are looking for. At that point, you can direct the Error to a specific view other than the default "Error" view.

For more information, take a look at Scott Guthrie's blog post about it.

Elijah Manor
Thanks for the extended information.I don't know what I did wrong, but I created a new project, ported all the existing views, controllers and models in it and now it works.Didn't know about the selective views though.
borisCallens
If logging of these exceptions is desired, would this be an acceptable place to add a codebehind to the view?
Peter J
Iconic, here's my "better late than never" reply to your comment: You can instead subclass the HandleErrorAttribute and override its "OnException" method: Then, insert whatever logging or custom actions that you desire. You can then either fully handle the exception (setting context.ExceptionHandled to true), or defer back to the base class's own OnException method for this. Here's an excellent article that may help with this: http://blog.dantup.me.uk/2009/04/aspnet-mvc-handleerror-attribute-custom.html
Funka
+6  A: 

It should also be noted that errors that don't set the http error code to 500

(e.g. UnauthorizedAccessException)

will not be handled by the HandleError filter.

Corin
True, but check out the RescueAttribute in MVC contrib (link in OP)
borisCallens
+1  A: 

Solution for http error code to 500 this is an attribute called [ERROR] put it on an action

public class Error: System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(System.Web.Mvc.ExceptionContext filterContext)
    {

            if (filterContext.HttpContext.IsCustomErrorEnabled)
            {
                filterContext.ExceptionHandled = true;

            }
            base.OnException(filterContext);
            //OVERRIDE THE 500 ERROR  
           filterContext.HttpContext.Response.StatusCode = 200;
    }

    private static void RaiseErrorSignal(Exception e)
    {
        var context = HttpContext.Current;
      // using.Elmah.ErrorSignal.FromContext(context).Raise(e, context);
    } 

}

//EXAMPLE:

[Error]
[HandleError]
[PopulateSiteMap(SiteMapName="Mifel1", ViewDataKey="Mifel1")]
public class ApplicationController : Controller
{
}
Raul
Raul, if you indent text with 4 spaces or more, it gets recognised as code (and gets syntax highlighting)
borisCallens