尝试在 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 , 提高警惕。
我有一个 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 , 提高警惕。