ASP.Net MVC Framework - Exception Handling

Note: This post is based on an early preview version of the ASP.Net MVC Framework and much will happen until the next milestone.

In this post I will show how we can handle errors that occur in a Controller’s Action method.
The Controller base class has a virtual method with the name OnError, this method takes three arguments, actionName, methodInfo and exception. It also has a return type of a Boolean. The idea when using the OnError method is to return true if we have handled the exception or false to letting ASP.Net handle it for us.

protected virtual bool OnError(string actionName, System.Reflection.MethodInfo methodInfo, Exception exception)

When an exception is thrown within our Action method, the OnError method will be executed. In the OnError method we can for example pass information to a View.

Here is an example of a Controller where I will Render a View called “Error” and pass the exception to the View:

public class HomeController : Controller
{
    protected override bool OnError(string actionName, System.Reflection.MethodInfo methodInfo, Exception exception)
    {
       RenderView("Error",exception.InnerException);
       return false;
    }

    [ControllerAction]
    public void Index()
    {
       int i = 0;
       int sum = 10 / i;

       RenderView("Index");
    }
}

When the Index Action method will be executed a DevidedByZero Exception will be thrown, when this happens the OnError method will be called and it will render a view and return false to specify that the error was handled.

To make sure to have a common View for displaying the error message, we put it into the Shared subfolder of the Views folder:

/Views
          /Shared
                Error.aspx


The Error View inherits the ViewData<Exception> class. To make this demo simple I just pass the Exception class to the View and show the value of the Message property:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Error.aspx.cs" Inherits="MvcApplication.Views.Error" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <div>
        <h1>Error on page</h1>
        <b><%=ViewData.Message %></b>
    </div>
</body>
</html>

20 Comments

  • Simple enough... I really wish I could be playing around with these bits already!


  • Mike Bosch:
    Soon you will :)

  • Dont play with us, just say when!... please.. :-))

  • Anything like the Flash in RoR or Monorail ?


  • J PHILIP:
    There is a TempData model which will store info into the Session and is uses a Dictionary and will survive to the next request. I will probably blog about this after I got some sleep ;) You can also use the ViewData property like:
    ViewData["Error"]= "Error on the page"
    and then in the View write:
    &lt;%= ViewData["Error"] %&gt;

  • Well, this is the first time I see something in the MVC framework that I think should be changed. Monorail rescue is a nicer alternative to achieve the same goal. If a rescue-style would be implemented then OnError would be usefull only for advanced scenarios.

  • I've been playing round with this as well and having an Error view is useful, but usually doesn't really solve all error scenarios well. After all you already get error routing from ASP.NET natively and that should still work with MVC.

    The real question is how to effectively render errors into the same page because that's by far the most common scenario. Validation errors, input errors, data load errors that might not warrant blowing out to a new page.

    The real question here becomes what's the 'page' model that can drive more complex scenarios especially where input is concerned without having a bunch of conditional rendering code embedded into the page ASP classic style.

    It's all nice and neat to have separate pages for everything when everything is nice and modular with one task per page which seems to be all that we've seen so far for MVC examples, but who builds pages like that anymore?


  • Dargos V:
    The Rescue-style is kind of nice, but if I understand it correctly you only specify the View that should display the exception message, but if I want to log an exception and do it every time an exception is thrown from an Action method the Rescue-style will probably not solve it, right!? And it’s very common that we log exceptions. So instead I should do like some other Java based MVC framework, and that is to point out an Exception handler controller. The onError method will give us more control and we can easy implement the rescue style to the onError method with a few lines of code.

  • Again, I just feel you rewrote Monorail just to put a Microsoft watermark on it.....
    Isn't that quite of you?


  • Liviu:
    I'm not an Microsoft employee ;)

  • Wouldn't it be better if RenderView's view argument be an enum type? Easier to refactor, wouldn't it?

  • I feel that the name (OnError) is misleading, since in .Net OnSomething methods generally have EventArgs as a parameter and have a corresponding event.

  • Not that this matters to much but...
    I was unable to get the OnError to work correctly in the CTP. I did find however that if you return "false" rather than "true" then everything works like a champ

    Just thought that if anyone else comes across this page that they should know that

    By the way... thanks for the post... really good stuff


  • meisinger:
    In pre-CTP we could use true to specify that the exception was handled, now in the CTP it's changed to false instead. I have updated the post. Thanks for the comment about this :)

  • I've been looking for some way to both effectively log errors, but also a way to ferry them from the business side to the view. Currently I'm using a delegate/event combination in C#. My business side makes an event available to the presentation classes. By doing this, the presentation page is notified immediately when an error occurrs.

    A resource that handled both error logging and validation errors as well as the display of both to the user would be great...

  • can we use microsoft exeception in mvc framework

  • This post indicates that it was on an early preview, but now it's 2009 and I don't think this post represents how things currently work. There is no OnError method to override on Controllers. Perhaps this was a feature that was introduced and then pulled? If it was never released, it might make sense to pull down this blog post as it may be confusing people.

  • I would agree with Tom; I had to read all the comments to figure out that this was a dead end

    Or perhaps put a comment at the top indicating that this is DEPRECATED

  • I'm with Tom and KD as well. After reading all about this, I now need to go and find out what the next approach is. A "DEPRECATED" notice is a great idea. Thanks for the read, though.

  • It seems the method has been renamed to OnException and instead of the 3 arguments mentioned in the article, it now receives a single ExceptionContext object which aggregates the controller, action and exception info along with a bunch of other stuff.

Comments have been disabled for this content.