3

I have implemented exception handling using below code.[Edited Start] I do not know why it is calling view twice. [Edited Done]

Basecontroller

public class BaseController : Controller
    {
        protected override void OnException(ExceptionContext filterContext)
        {
            if (filterContext.HttpContext.IsCustomErrorEnabled)
            {
                filterContext.ExceptionHandled = true;

                if (filterContext.Exception.GetType() == typeof(ArgumentOutOfRangeException))
                {
                    this.View("OutOfRange").ExecuteResult(this.ControllerContext);
                }
                else
                {
                    this.View("Error").ExecuteResult(this.ControllerContext);
                }
            }

            base.OnException(filterContext);
        }
    }

HomeController

public class HomeController : BaseController
{
        public ActionResult Exception2()
        {
            throw (new ArgumentOutOfRangeException());
        }

        public ActionResult Exception3()
        {
            throw (new Exception());
        }
}

Error View (Shared folder only)

@model System.Web.Mvc.HandleErrorInfo
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <title>Error</title>
</head>
<body>
    <h2>
        Sorry, an error occurred while processing your request.
    </h2>
    <h3>
        @if (Model != null)
        {
            <p>@Model.Exception.GetType().Name<br />
                thrown in @Model.ControllerName @Model.ActionName</p>
            <br />
            @Model.Exception
        }
    </h3>
</body>
</html>

OutOfRange view (Shared folder only)

@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <title>OutOfRange Exception</title>
</head>
<body>
    <div>
        <h3>
            @if (Model != null)
            {
                <p>@Model.Exception.GetType().Name<br />
                    thrown in @Model.ControllerName @Model.ActionName</p>
                <br />
                @Model.Exception
            }
        </h3>
    </div>
</body>
</html>

Execution URL : http://[domainName]/Home/Exception2

Here it is working fine. [EDITED : Here it also call twice.]

enter image description here

Execution URL : http://[domainName]/Home/Exception3

Here it is not working fine. You can see that "Sorry, an error occurred while processing your request." is coming twice. When I debugged the application using above URL, Error view called twice ( First time Model is null and second time Model contains some value). May I know what is wrong with my implementation? enter image description here

Kenny Evitt
  • 9,291
  • 5
  • 65
  • 93
alok_dida
  • 1,723
  • 2
  • 17
  • 36

3 Answers3

7

Things to try:

  1. Remove the default HandleError global action filter attribute from your Global.asax if it is present. When you create a new ASP.NET MVC 3 application the default template registers it inside the RegisterGlobalFilters method. So comment out the line which registers this attribute.
  2. Enable custom errors in your web.config:

    <customErrors mode="On" />
    

UPDATE:

If you want to pass a model to the Error.cshtml view (as it is strongly typed to HandleErrorInfo) you could do the following:

else
{
    string controllerName = filterContext.RouteData.GetRequiredString("controller");
    string actionName = filterContext.RouteData.GetRequiredString("action");
    var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
    var result = new ViewResult
    {
        ViewName = "Error",
        ViewData = new ViewDataDictionary<HandleErrorInfo>(model)
    };
    filterContext.Result = result;
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • If i remove the HandleError than HandleErrorInfo model is coming null. :( . – alok_dida Jul 04 '12 at 06:39
  • Well, that's absolutely normal. I can't see you passing any model inside your custom `OnException` method. You just render the view. You need to pass a model to this view if you expect to get some model in it. – Darin Dimitrov Jul 04 '12 at 06:43
  • Hmmm.How do I get HandleErrorInfo in View ? Do i get this object in OnException override method? – alok_dida Jul 04 '12 at 06:46
  • 1
    You are like my Godfather. It works!!! I learned a lot of things from your posts/blogs. Thanks a ton for it!!! – alok_dida Jul 04 '12 at 07:01
  • Just for the knowledge. When I am register HandleErrorAttribute in global.asax file using following code. filters.Add(new HandleErrorAttribute { ExceptionType = typeof(ArgumentOutOfRangeException), View = "OutOfRange", Order = 2 }); I have defined OutOfrange view in Shared folder but its looking it in "Home" view folder. Why is it so? – alok_dida Jul 04 '12 at 07:08
1

Add base.OnException(filterContext); before if (filterContext.HttpContext.IsCustomErrorEnabled)

      protected override void OnException(ExceptionContext filterContext)
      {
          base.OnException(filterContext);
         if (filterContext.HttpContext.IsCustomErrorEnabled)

      }
swapneel
  • 3,061
  • 1
  • 25
  • 32
1

I had the same problem, but I managed to resolve the error by adding:

Response.End();

To the end of my OnException method.

I know it's not the ideal resolution, but, it did at least get me out of a bind until such a time as I can investigate a more complete option.

Andy N
  • 11
  • 1