Asp.net mvc ASP.NET MVC Ajax错误处理

Asp.net mvc ASP.NET MVC Ajax错误处理,asp.net-mvc,jquery,asp.net-mvc-3,Asp.net Mvc,Jquery,Asp.net Mvc 3,当jQueryAjax调用动作时,如何处理控制器中抛出的异常 例如,我想要一个全局javascript代码,在ajax调用期间在任何类型的服务器异常上执行,如果处于调试模式,则显示异常消息,或者仅显示正常错误消息 在客户端,我将调用关于ajax错误的函数 在服务器端,是否需要编写自定义actionfilter?如果服务器发送的状态代码不同于200,则执行错误回调: $.ajax({ url: '/foo', success: function(result) {

当jQueryAjax调用动作时,如何处理控制器中抛出的异常

例如,我想要一个全局javascript代码,在ajax调用期间在任何类型的服务器异常上执行,如果处于调试模式,则显示异常消息,或者仅显示正常错误消息

在客户端,我将调用关于ajax错误的函数


在服务器端,是否需要编写自定义actionfilter?

如果服务器发送的状态代码不同于200,则执行错误回调:

$.ajax({
    url: '/foo',
    success: function(result) {
        alert('yeap');
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert('oops, something bad happened');
    }
});
要注册全局错误处理程序,可以使用以下方法:

另一种方法是使用JSON。因此,您可以在服务器上编写一个自定义操作筛选器,捕获异常并将其转换为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
    }
});

如果服务器发送的某些状态代码不同于200,则执行错误回调:

$.ajax({
    url: '/foo',
    success: function(result) {
        alert('yeap');
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert('oops, something bad happened');
    }
});
要注册全局错误处理程序,可以使用以下方法:

另一种方法是使用JSON。因此,您可以在服务器上编写一个自定义操作筛选器,捕获异常并将其转换为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
    }
});

为了在客户端处理来自ajax调用的错误,您可以为ajax调用的
error
选项分配一个函数

要全局设置默认值,可以使用此处描述的函数:
.

要在客户端处理来自ajax调用的错误,您需要为ajax调用的
error
选项分配一个函数

要全局设置默认值,可以使用此处描述的函数:
.

在谷歌搜索之后,我基于MVC操作过滤器编写了一个简单的异常处理:

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>

$(文档).ajaxError(函数(e、jqxhr、设置、异常){
e、 停止传播();
if(jqxhr!=null)
警报(jqxhr.responseText);
});
最后,您应该启用自定义错误。
然后享受它:)

在谷歌搜索之后,我基于MVC动作过滤器编写了一个简单的异常处理:

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>

$(文档).ajaxError(函数(e、jqxhr、设置、异常){
e、 停止传播();
if(jqxhr!=null)
警报(jqxhr.responseText);
});
最后,您应该启用自定义错误。
然后享受它:)

我做了一个快速的解决方案,因为我时间不多,效果还不错。虽然我认为更好的选择是使用异常过滤器,但如果需要简单的解决方案,我的解决方案可能会有所帮助

我做了以下几件事。在控制器方法中,我返回了一个JsonResult,数据中有一个属性“Success”:

    [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调用中,我只是要求该属性知道我是否有异常:

$.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

我做了一个快速的解决方案,因为我时间不够,效果还不错。虽然我认为更好的选择是使用异常过滤器,但如果需要简单的解决方案,我的解决方案可能会有所帮助

我做了以下几件事。在控制器方法中,我返回了一个JsonResult,数据中有一个属性“Success”:

    [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调用中,我只是要求该属性知道我是否有异常:

$.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

不幸的是,这两个答案对我都不好。令人惊讶的是,解决方案要简单得多。从控制器返回:

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

并将其作为客户端上的标准HTTP错误进行处理。

不幸的是,这两个答案对我都不好。令人惊讶的是,解决方案要简单得多。从控制器返回:

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

并将其作为客户端上的标准HTTP错误进行处理。

与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);
        }
    }
}

希望这对其他人有帮助

与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);
        }
    }
}

希望这对其他人有帮助

谢谢你,后者正是我想要的。那么对于asp.net mvc异常,是否有一种特殊的方式需要抛出它,以便jquery错误处理程序能够捕获它?@Lol coder,无论您在控制器操作中如何抛出异常,服务器都将返回500个状态代码,并执行
错误
回调。谢谢,非常好,这正是我想要的。状态码500不是有点错吗?引用这一章:“没有意识到4xx错误意味着我搞砸了,5xx意味着你搞砸了”——我是客户端,你是服务器。这个答案对较新版本的ASPNET仍然有效?谢谢你,我一直在寻找后者。那么对于asp.net mvc异常,是否有一种特殊的方式需要抛出它,以便jquery错误处理程序能够捕获它?@Lol coder,无论您在控制器操作中如何抛出异常,服务器都将返回500个状态代码,并执行
错误
回调。谢谢,非常好,这正是我想要的。状态码500不是有点错吗?引用这一章:“没有意识到4xx错误意味着我搞砸了,5xx意味着你搞砸了”——我是客户端,你是服务器。这个答案对较新版本的ASPNET仍然有效?请参阅以获得一个好的示例。Darins对此帖子的回答很好,但不要为错误设置正确的状态代码。遗憾的是,该链接现在已断开。wayback机器上的链接就是这个链接:请参阅,以获得一个好的示例。Darins对这篇文章的回答是好的,但不要设置co