2

I have setup so that if an Exception is thrown I can display it with my custom error page. But in some cases I don't want to be navigated to the error page, but want it to display a simple dialog window.

public ActionResult Page1()
{
    //The custom error page shows the exception, if one was thrown

    throw new Exception( "An exception was thrown" );

    return View();
}


public ActionResult Page2()
{
    //A dialog should show the exception, if one was thrown

    try
    {
        throw new Exception( "An exception was thrown" );
    }
    catch( Exception ex )
    {
        ViewData["exception"] = ex;
    }
    return View();
}

Is it possible to have a CustomAttribute to handle an exception which has been thrown in an Controller action? If I added CatchException to Page2, can I automate the process of storing the exception in the ViewData, each time an exception was thrown. I don't have much experience of CustomAttributes and I'd be much appreciated if you could help me.

The Page2 example works perfectly fine, I just want to make the code cleaner as it isn't really pretty to have try catches in every action (where I want to show a dialog).

I am using .NET MVC 4.

LazyTarget
  • 879
  • 1
  • 14
  • 30

2 Answers2

3

You can create a base controller that catch the exceptions and handle it for you. Also, looks like the Controllers already have a mechanism to do that for you. You'll have to override the OnException method inside the controller. You can get a good example here: Handling exception in ASP.NET MVC

Also, there's another answer on how to use the OnException here: Using the OnException

By using that, your code will be cleaner, since you will not be doing a lot of try/catch blocks.

You'll have to filter the exception you wanna handle. Like this:

protected override void OnException(ExceptionContext contextFilter)
{
    // Here you test if the exception is what you are expecting
    if (contextFilter.Exception is YourExpectedException)
    {
        // Switch to an error view
        ...
    }
    //Also, if you want to handle the exception based on the action called, you can do this:
    string actionName = contextFilter.RouteData.Values["action"];
    //If you also want the controller name (not needed in this case, but adding for knowledge)
    string controllerName = contextFilter.RouteData.Values["controller"];
    string[] actionsToHandle = {"ActionA", "ActionB", "ActionC" };

    if (actionsTohandle.Contains(actionName)) 
    {
         //Do your handling.
    }

    //Otherwise, let the base OnException method handle it.
    base.OnException(contextFilter);
}
Community
  • 1
  • 1
digaomatias
  • 1,164
  • 10
  • 21
  • From the overriden OnException I don't know if I want to catch it and show a dialog, or let it go to the error page. Whether to show the error page or dialog depends on the action and not by the Exception type, so I can't do a check in OnException if the exception was a NullReferenceException then it should "blow". Can you understand how I am thinking? – LazyTarget Oct 29 '12 at 20:06
  • Yes, I understood. That's why you'll have to filter the exception you want to handle. I'll edit the code to show what I meant. – digaomatias Oct 29 '12 at 23:07
  • Oh yeah of course. I can just compare the action names. Thank you :) – LazyTarget Oct 31 '12 at 11:55
0

You can create subclass of Exception class, and catch it in your Page 2

internal class DialogException : Exception
{}

public ActionResult Page2()
{
    //This should a dialog if an exception was thrown

    try
    {
        //throw new Exception( "An exception was thrown, redirect" );
        throw new DialogException( "An exception was thrown, show dialog" );
    }
    catch( DialogException ex )
    {
        ViewData["exception"] = ex;
    }
    return View();
}
Hamlet Hakobyan
  • 32,965
  • 6
  • 52
  • 68
  • The thing is that I already have some custom exception types, which have specific properties. So I can't really create a new `DialogException` and inherit of of Exception. – LazyTarget Oct 29 '12 at 20:01