asp.net-mvc-2handleerror

How can I make HandleErrorAttribute work with Ajax?


In my ASP.NET MVC 2 application I use HandleErrorAttribute to display a custom error page in case of unhandled exceptions, and it works perfectly unless the exception happens in an action called by Ajax.ActionLink. In this case nothing happens. Is it possible to use HandleErrorAttribute to update the target element with the contents of an "Error.ascx" partial view?


Solution

  • To achieve this you could write a custom action filter:

    public class AjaxAwareHandleErrorAttribute : HandleErrorAttribute
    {
        public string PartialViewName { get; set; }
    
        public override void OnException(ExceptionContext filterContext)
        {
            // Execute the normal exception handling routine
            base.OnException(filterContext);
    
            // Verify if AJAX request
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                // Use partial view in case of AJAX request
                var result = new PartialViewResult();
                result.ViewName = PartialViewName;
                filterContext.Result = result;
            }
        }
    }
    

    And then specify the partial view to be used:

    [AjaxAwareHandleError(PartialViewName = "~/views/shared/error.ascx")]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        public ActionResult SomeAction() 
        {
            throw new Exception("shouldn't have called me");
        }
    }
    

    And finally in your view assuming you have the following link:

    <%= Ajax.ActionLink("some text", "someAction", new AjaxOptions { 
        UpdateTargetId = "result", OnFailure = "handleFailure" }) %>
    

    You could make the handleFailure function to update the proper div:

    <script type="text/javascript">
        function handleFailure(xhr) {
            // get the error text returned by the partial
            var error = xhr.get_response().get_responseData();
    
            // place the error text somewhere in the DOM
            document.getElementById('error').innerHTML = error;
        }
    </script>