Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Ajax Error handling

People also ask

How can handle exception in Ajax call in MVC?

For handling errors from ajax calls on the client side, you assign a function to the error option of the ajax call. To set a default globally, you can use the function described here: http://api.jquery.com/jQuery.ajaxSetup.

How can we handle exception handling in Ajax?

Example: We are going to see how to use AJAX fail() methods to handle the error in the HTTP requests. The fail() callback takes 3 parameters where the first parameter is a JSON error object, the second parameter is given a reason in text format and the last parameter is for the error thrown by the HTTP request.

Can we use Ajax in MVC?

The MVC Framework contains built-in support for unobtrusive Ajax. You can use the helper methods to define your Ajax features without adding a code throughout all the views. This feature in MVC is based on the jQuery features. To enable the unobtrusive AJAX support in the MVC application, open the Web.

How does Ajax work in MVC?

It is a client-side script that communicates to and from a server/database without the need for a postback or a complete page refresh. The Ajax speeds up response time. In other words, Ajax is the method of exchanging data with a server, and updating parts of a web page, without reloading the entire page.


If the server sends some status code different than 200, the error callback is executed:

$.ajax({
    url: '/foo',
    success: function(result) {
        alert('yeap');
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert('oops, something bad happened');
    }
});

and to register a global error handler you could use the $.ajaxSetup() method:

$.ajaxSetup({
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert('oops, something bad happened');
    }
});

Another way is to use JSON. So you could write a custom action filter on the server which catches exception and transforms them into JSON response:

public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        filterContext.ExceptionHandled = true;
        filterContext.Result = new JsonResult
        {
            Data = new { success = false, error = filterContext.Exception.ToString() },
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };
    }
}

and then decorate your controller action with this attribute:

[MyErrorHandler]
public ActionResult Foo(string id)
{
    if (string.IsNullOrEmpty(id))
    {
        throw new Exception("oh no");
    }
    return Json(new { success = true });
}

and finally invoke it:

$.getJSON('/home/foo', { id: null }, function (result) {
    if (!result.success) {
        alert(result.error);
    } else {
        // handle the success
    }
});

After googling I write a simple Exception handing based on MVC Action Filter:

public class HandleExceptionAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
        {
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new
                {
                    filterContext.Exception.Message,
                    filterContext.Exception.StackTrace
                }
            };
            filterContext.ExceptionHandled = true;
        }
        else
        {
            base.OnException(filterContext);
        }
    }
}

and write in global.ascx:

 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
 {
      filters.Add(new HandleExceptionAttribute());
 }

and then write this script on the layout or Master page:

<script type="text/javascript">
      $(document).ajaxError(function (e, jqxhr, settings, exception) {
                       e.stopPropagation();
                       if (jqxhr != null)
                           alert(jqxhr.responseText);
                     });
</script>

Finally you should turn on custom error. and then enjoy it :)


Unfortunately, neither of answers are good for me. Surprisingly the solution is much simpler. Return from controller:

return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);

And handle it as standard HTTP error on client as you like.


I did a quick solution because I was short of time and it worked ok. Although I think the better option is use an Exception Filter, maybe my solution can help in the case that a simple solution is needed.

I did the following. In the controller method I returned a JsonResult with a property "Success" inside the Data:

    [HttpPut]
    public JsonResult UpdateEmployeeConfig(EmployeConfig employeToSave) 
    {
        if (!ModelState.IsValid)
        {
            return new JsonResult
            {
                Data = new { ErrorMessage = "Model is not valid", Success = false },
                ContentEncoding = System.Text.Encoding.UTF8,
                JsonRequestBehavior = JsonRequestBehavior.DenyGet
            };
        }
        try
        {
            MyDbContext db = new MyDbContext();

            db.Entry(employeToSave).State = EntityState.Modified;
            db.SaveChanges();

            DTO.EmployeConfig user = (DTO.EmployeConfig)Session["EmployeLoggin"];

            if (employeToSave.Id == user.Id)
            {
                user.Company = employeToSave.Company;
                user.Language = employeToSave.Language;
                user.Money = employeToSave.Money;
                user.CostCenter = employeToSave.CostCenter;

                Session["EmployeLoggin"] = user;
            }
        }
        catch (Exception ex) 
        {
            return new JsonResult
            {
                Data = new { ErrorMessage = ex.Message, Success = false },
                ContentEncoding = System.Text.Encoding.UTF8,
                JsonRequestBehavior = JsonRequestBehavior.DenyGet
            };
        }

        return new JsonResult() { Data = new { Success = true }, };
    }

Later in the ajax call I just asked for this property to know if I had an exception:

$.ajax({
    url: 'UpdateEmployeeConfig',
    type: 'PUT',
    data: JSON.stringify(EmployeConfig),
    contentType: "application/json;charset=utf-8",
    success: function (data) {
        if (data.Success) {
            //This is for the example. Please do something prettier for the user, :)
            alert('All was really ok');                                           
        }
        else {
            alert('Oups.. we had errors: ' + data.ErrorMessage);
        }
    },
    error: function (request, status, error) {
       alert('oh, errors here. The call to the server is not working.')
    }
});

Hope this helps. Happy code! :P