jQuery ASP.NET MVC Ajax 错误处理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4707755/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 17:45:52  来源:igfitidea点击:

ASP.NET MVC Ajax Error handling

asp.net-mvcjqueryasp.net-mvc-3

提问by Shawn Mclean

How do I handle exceptions thrown in a controller when jquery ajax calls an action?

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

For example, I would like a global javascript code that gets executed on any kind of server exception during an ajax call which displays the exception message if in debug mode or just a normal error message.

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

On the client side, I will call a function on the ajax error.

在客户端,我会在 ajax 错误时调用一个函数。

On the server side, Do I need to write a custom actionfilter?

在服务器端,我需要编写自定义 actionfilter 吗?

回答by Darin Dimitrov

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

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

$.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()方法:

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

另一种方法是使用 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
        };
    }
}

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

回答by Arash Karami

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

谷歌搜索后,我写了一个简单的基于 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);
        }
    }
}

and write in global.ascx:

并在 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 :)

最后,您应该打开自定义错误。然后享受它:)

回答by alehro

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.

并根据需要在客户端将其作为标准 HTTP 错误处理。

回答by Rymnel

In agreement with aleho's response here's a complete example. It works like a charm and is super simple.

与 aleho 的回应一致,这里有一个完整的例子。它就像一个魅力,非常简单。

Controller code

控制器代码

[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 code in the view

视图中的 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.
    }
});

Hope this helps someone else!

希望这对其他人有帮助!

回答by Daniel Silva

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:

我做了以下事情。在控制器方法中,我在数据中返回了一个带有“成功”属性的 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 }, };
    }

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

后来在 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.')
    }
});

Hope this helps. Happy code! :P

希望这可以帮助。快乐码!:P

回答by Brian Ball

For handling errors from ajax calls on the client side, you assign a function to the erroroption of the ajax call.

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

To set a default globally, you can use the function described here: http://api.jquery.com/jQuery.ajaxSetup.

要全局设置默认值,您可以使用此处描述的函数:http: //api.jquery.com/jQuery.ajaxSetup