尝试在 asp.net 中的异步函数中捕获处理程序 mvc5 在 chrome 和 IE11 中表现不同

Try catch handler in async function in asp.net mvc5 behave differently in chrome and IE11

我有一个 asp.net mvc 项目,它使用 Entity Framework 6.The 索引页在 gridMVC 中获取记录。我在顶部有一个添加新记录按钮以添加在 bootstrap 模式弹出窗口中打开的新记录。一切正常,直到用户尝试输入重复记录。下面是我完成异常处理的代码,每当添加失败时,它应该抛出一个异常,向用户显示一个警告框,通知他添加重复记录。

[ValidateAntiForgeryToken]
[HttpPost]
public async Task<ActionResult> Create([Bind(Include = "Id,Date,PersonelID,OnCallType,Comments")] QnsScheduleNew1 qnsnew1)
{
    if (ModelState.IsValid)
    {
        db.QnsScheduleNew1 .Add(qnsnew1);
        try
        {
            await db.SaveChangesAsync();
        }
        catch(Exception e)
        {
            //return Json(new { RedirectUrl = Url.Action("Index") });
            throw new Exception("Server error");
        }
        return Json(new { RedirectUrl = Url.Action("Index") });
    }

在 _Create.cshtml 中,我使用 ajax 形式的 OnFailure 事件来捕获异常。

@using (Ajax.BeginForm("Create", "Queens", new AjaxOptions() { UpdateTargetId = "validation", HttpMethod = "Post", OnSuccess = "createsuccess",OnFailure="createfailure" }, new { id = "Create" }))
{
    //some code
}

而使用的javascript是

<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<link href="~/Content/bootstrap-datepicker3.css" rel="stylesheet" />

<script src="~/Scripts/bootstrap-datepicker.js"></script>

<script type="text/javascript">
    function createsuccess(data) {
        if (data.RedirectUrl)
            window.location.href = data.RedirectUrl;
    }
    function createfailure(data) {
        alert("Server error has occured. Are you trying to add duplicate Record!!!");
    }
</script>
<script>
    $(function () {
        $('.datepicker').datepicker({
            format: "yyyy/mm/dd",
            pickDate: true
        });
        $(".datepicker").datepicker('setValue', new Date());
    });
</script>

在 Chrome 中一切正常,但在 IE11 中,每当添加任何记录时,它都会提醒用户添加重复记录。

我在IE中运行ning时调试过代码。它最初不去 catch 块,但在返回 Json 后,它会去 catch 块并执行它。为什么会这样?调试还告诉我,我的所有方法都被命中了两次,代码执行的方式很奇怪,它可以从任何东西跳转,但在 Chrome 中比在 IE11 中给出预期的结果。我假设这是因为异步编程方式,您无法预测哪个线程将按哪个顺序 运行。

谁能详细解释一下这个以及如何解决这个问题以便在 IE11 中工作。

我不确定 Chrome 和 IE11 在这方面的区别,但也许解决一些潜在问题也能解决这个问题。

首先,在 try...catch 中 catch 仅引发异常会破坏使用 try...catch 的全部目的。如果没有它,您的代码将表现得完全相同。

其次,您的应用程序不应依赖于发生的服务器错误。服务器错误应该是指示真正问题的异常。故意返回 500 是不好的,除非服务器出现某种灾难性故障。现有实体不是灾难性故障。

通常,根据 REST 设计,您应该 return 一个合适的状态代码。但是,实际上并没有适用于已存在实体的 HTTP 状态代码。因此,我会说 return 200 OK,暗示请求本身没问题,然后在响应正文中包含一些指示,表明创建实体时出现问题。例如:

 try
 {
     await db.SaveChangesAsync();
 }
 catch(Exception e)
 {
     return Json(new { created = false });
 }

 return Json(new { created = true, RedirectUrl = Url.Action("Index") });

然后,您的 createfailure 函数应该只关注从真正的服务器错误中恢复。您的 createsuccess 函数应检查响应中 created 的值,并在 true 时重定向或在 false 时发出警报。

编辑

从技术上讲,"Created" 有一个特殊的状态代码:201。您可以选择 return 使用此状态代码的成功响应,然后如果状态代码只是 200 而不是 201 , 提高警惕。