ASP.NET MVC Ajaxerror handling
当jquery ajax调用操作时,如何处理控制器中抛出的exception?
例如,我想要一个全局的javascript代码,在ajax调用期间执行任何types的服务器exception,如果处于debugging模式或只是一个普通的错误消息,则会显示exception消息。
在客户端,我将调用ajax错误的函数。
在服务器端,我是否需要编写一个自定义actionfilter?
如果服务器发送一些不同于200的状态码,则会执行错误callback:
$.ajax({ url: '/foo', success: function(result) { alert('yeap'); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert('oops, something bad happened'); } });
并注册一个全局error handling程序,您可以使用$.ajaxSetup()
方法:
$.ajaxSetup({ error: function(XMLHttpRequest, textStatus, errorThrown) { alert('oops, something bad happened'); } });
另一种方法是使用JSON。 所以你可以在服务器上写一个自定义的动作filter来捕获exception,并将它们转换成JSON响应:
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 }; } }
然后用这个属性来修饰你的控制器动作:
[MyErrorHandler] public ActionResult Foo(string id) { if (string.IsNullOrEmpty(id)) { throw new Exception("oh no"); } return Json(new { success = true }); }
最后调用它:
$.getJSON('/home/foo', { id: null }, function (result) { if (!result.success) { alert(result.error); } else { // handle the success } });
谷歌search后,我写了一个简单的exception处理基于MVC行动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); } } }
并写入global.ascx:
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleExceptionAttribute()); }
然后在布局或母版页上编写该脚本:
<script type="text/javascript"> $(document).ajaxError(function (e, jqxhr, settings, exception) { e.stopPropagation(); if (jqxhr != null) alert(jqxhr.responseText); }); </script>
最后你应该打开自定义错误。 然后享受它:)
不幸的是,这两个答案都不适合我。 令人惊讶的是,解决scheme要简单得多。 从控制器返回:
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);
并把它作为客户端的标准HTTPerror handling,只要你喜欢。
与aleho的回答一致,这里是一个完整的例子。 它像一个魅力,超级简单。
控制器代码
[HttpGet] public async Task<ActionResult> ChildItems() { var client = TranslationDataHttpClient.GetClient(); HttpResponseMessage response = await client.GetAsync("childItems); if (response.IsSuccessStatusCode) { string content = response.Content.ReadAsStringAsync().Result; List<WorkflowItem> parameters = JsonConvert.DeserializeObject<List<WorkflowItem>>(content); return Json(content, JsonRequestBehavior.AllowGet); } else { return new HttpStatusCodeResult(response.StatusCode, response.ReasonPhrase); } } }
在视图中的Javascript代码
var url = '@Html.Raw(@Url.Action("ChildItems", "WorkflowItemModal")'; $.ajax({ type: "GET", dataType: "json", url: url, contentType: "application/json; charset=utf-8", success: function (data) { // Do something with the returned data }, error: function (xhr, status, error) { // Handle the error. } });
希望这可以帮助别人!
我做了一个快速的解决scheme,因为我时间不够,它运作良好。 虽然我认为更好的select是使用exceptionfilter,也许我的解决scheme可以帮助在需要一个简单的解决scheme的情况下。
我做了以下。 在控制器方法中,我返回了一个带有“成功”属性的JsonResult,
[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 }, }; }
后来在ajax调用中,我只是要求这个属性来知道我是否有一个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.') } });
希望这可以帮助。 快乐的代码! :P
为了处理来自客户端Ajax调用的错误,你需要为ajax调用的error
选项分配一个函数。
要全局设置默认值,可以使用此处所述的函数: http : //api.jquery.com/jQuery.ajaxSetup 。