Reporting errors from Ajax invoked PartialView methods in MVC Reporting errors from Ajax invoked PartialView methods in MVC ajax ajax

Reporting errors from Ajax invoked PartialView methods in MVC


Controller action:

public ActionResult Foo(){    // Obviously DoSomething could throw but if we start     // trying and catching on every single thing that could throw    // our controller actions will resemble some horrible plumbing code more    // than what they normally should resemble: a.k.a being slim and focus on    // what really matters which is fetch a model and pass to the view    // Here you could return any type of view you like: JSON, HTML, XML, CSV, PDF, ...    var model = DoSomething();    return PartialView(model);}

Then we define a Global error handler for our application:

protected void Application_Error(object sender, EventArgs e){    var exception = Server.GetLastError();    var httpException = exception as HttpException;    Response.Clear();    Server.ClearError();    if (new HttpRequestWrapper(Request).IsAjaxRequest())    {        // Some error occurred during the execution of the request and         // the client made an AJAX request so let's return the error        // message as a JSON object but we could really return any JSON structure        // we would like here        Response.StatusCode = 500;        Response.ContentType = "application/json";        Response.Write(new JavaScriptSerializer().Serialize(new         {             errorMessage = exception.Message         }));        return;    }    // Here we do standard error handling as shown in this answer:    // http://stackoverflow.com/q/5229581/29407    var routeData = new RouteData();    routeData.Values["controller"] = "Errors";    routeData.Values["action"] = "General";    routeData.Values["exception"] = exception;    Response.StatusCode = 500;    if (httpException != null)    {        Response.StatusCode = httpException.GetHttpCode();        switch (Response.StatusCode)        {            case 404:                routeData.Values["action"] = "Http404";                break;            case 500:                routeData.Values["action"] = "Http500";                break;        }    }    IController errorsController = new ErrorsController();    var rc = new RequestContext(new HttpContextWrapper(Context), routeData);    errorsController.Execute(rc);}

Here's how the ErrorsController used in the global error handler could look like. Probably we could define some custom views for the 404 and 500 actions:

public class ErrorsController : Controller{    public ActionResult Http404()    {        return Content("Oops 404");    }    public ActionResult Http500()    {        return Content("500, something very bad happened");    }}

Then we could subscribe for a global error handler for all AJAX errors so that we don't have to repeat this error handling code for all AJAX requests but if we wanted we could repeat it:

$('body').ajaxError(function (evt, jqXHR) {    var error = $.parseJSON(jqXHR.responseText);    alert('An error occured: ' + error.errorMessage);});

And finally we fire an AJAX request to the controller action that we hope will return an HTML partial in this case:

$.ajax({    url: 'whatever/trevor',    success: function (html) {        $container.html(html);    }});


Create an overriden version of HandleErrorAttribute (JsonHandleErrorAttribute ?) and add [JsonHandleError] on your json action.

Have a look at AjaxAuthorizeAttribute in asp.net mvc [handleerror] [authorize] with JsonResult?