与 ASP.net MVC 中 Ajax 请求中的错误处理有关的疑问
Posted
技术标签:
【中文标题】与 ASP.net MVC 中 Ajax 请求中的错误处理有关的疑问【英文标题】:Doubts relating to error handling in Ajax requests in ASP.net MVC 【发布时间】:2011-11-19 04:19:25 【问题描述】:几天来,我一直在使用 Visual Studio 2010 在本地计算机上开发 Web 应用程序。昨晚,我在 IIS 7 上部署了我的应用程序,但令人沮丧地偶然发现了一个主要的显示障碍。该问题与 Ajax 请求中的错误处理有关。首先,我有一些适用于 ajax 请求的编辑屏幕。这是 Ajax 编辑屏幕的 ajax 部分的样子。
@using (Ajax.BeginForm("_CityEdit", null, new AjaxOptions HttpMethod = "Post", UpdateTargetId = "content",
LoadingElementId="imgSaveLoading", OnFailure="onError",
OnSuccess = "onSuccess" , new id = "frmCity" ))
<img id="imgSaveLoading" src="@Url.Content("~/Content/Telerik/Vista/loading.gif")" class="ajax-loader-user" />
<div class="content" id="content">
@html.RenderPartial("_CityEdit");
</div>
<!-- Some Other code here -->
我依赖于上述 Ajax.BeginForm() 的“onError”回调。所以在我的控制器中,每当我想向用户显示错误(模型错误或任何其他错误)时,我只是乐观地将服务器响应设置为 500(内部服务器错误),希望这会导致 Ajax.BeginForm 的“OnError”处理程序() 被调用。这是我如何在控制器中执行此操作的 sn-p。
[HttpPost]
public ActionResult _CityEdit(CityViewModel viewModel)
city = cityManager.FindCity(viewModel.City.Id, false);
// Validate Model here
if (!TryUpdateModel(city, "City"))
Response.StatusCode = 500;
return PartialView("_CityEdit", viewModel);
从上面的代码可以看出,我返回了 PartialView,如果它包含模型错误,它们将自动显示在 Ajax 编辑屏幕上。然后在“OnError”javascript 中,我只需将相关的 div 替换为控制器返回的 PartialView,如下所示。
function onError(xhr)
$('#content').html(xhr.responseText);
这一切都在我的开发机器上运行良好。当我在 IIS 7 上部署我的应用程序并从 Windows XP 框(使用 IE 8 或 Chrome)而不是 PartialView 访问它时,浏览器只显示默认的“500 内部服务器错误”屏幕。所以我有几个疑虑导致我昨晚睡不好。
我用于 Ajax 编辑的方法是否合理。如果不是,我本可以处理 Ajax 编辑(具有显示模型错误的能力)的其他方式。
自从我开发这些模块几天以来并付出了相当大的努力,是否有任何变通方法可以让它在 XP 盒子上运行。基本上,如果我能以某种方式阻止浏览器显示其默认的“500 Internal Server Error”屏幕,那将是理想的。
这种方法是否适用于 windows 7,因为我在用于浏览站点的同一台 windows 7 机器上安装了 IIS 7,或者它只是适用于 windows 7。
如果有其他建议,请继续。
编辑: 我找到了解决我的问题的方法。所以这意味着没有回答 2 和 3 的疑问。基本上,web.config 中的以下条目会阻止浏览器显示网站的默认浏览器页面。
<system.webServer>
<httpErrors errorMode="Detailed"/>
</system.webServer>
但这仍然排除了我的第一个疑问。我是否使用了合理的 Ajax 编辑方法?
我用提琴手检查了响应,是 IIS 发送了服务器错误 500 的默认错误页面。因此需要将其配置为返回“详细”响应。我们可以使用 IIS 管理器来做到这一点。我遵循的另一个选项是在应用程序的 web.config 文件中的应用程序级别定义它。
但是,我又陷入了两难境地,是采用这种方法还是重新编写整个应用程序。出现的问题是,如果确实有一些模块因 500 内部服务器而失败,我的代码会在浏览器中暴露,因为 errorMode 设置为“详细”。因此,当我将响应错误代码设置为 500 并且如果应用程序的任何其他部分失败(我不是设置 500 状态代码的那个)时,我需要一些方法来提供我的自定义响应,那么应该发送默认错误页面而不是公开我的代码通过“详细”响应。请帮忙。
问候, 尼文。
【问题讨论】:
奇怪的是,详细的错误页面可以解决您的问题。你的意思是整个页面被错误屏幕代替,而不是内容div?这是否也更新了浏览器中的当前 URL?这听起来更像是 AJAX 调用本身失败了,因为它不应该导致正常的 GET/POST - 它应该只通过 JS 呈现。我认为您的技术是可以接受的,因为您永远无法防止 500 次 AJAX 调用无论如何 -OnError
应该足以处理它们。我认为您应该先找出导致OnError
无法在已部署环境中工作的原因。
@bzlm,当我将响应状态设置为 500 时,我很确定浏览器忽略了我从控制器返回的给定 ajax 请求的整个响应。不知何故,浏览器显示了自己的“500内部服务器错误”屏幕。但是您是对的,只有内容 div 的内容被“500 Internal Server Error”页面替换。我的 html 页面的其他部分保持不变。但是,我不得不阻止浏览器弹出它的错误页面,实际上“errorMode”解决了这个问题。我没有更改我的应用程序中的任何其他内容(据我所知)。谢谢。
@bzlm,这是我找到解决方案的地方。 bala-krishna.com/…
我明白了。听起来 GoDaddy 实际上并没有向浏览器返回 500 的 HTTP 状态代码,因为您的 OnError
处理程序没有触发。我猜他们使用的基本 Web.config 或 IIS 设置被 httpErrors errorMode
覆盖,副作用是响应代码实际上是 500。总而言之,我会说你的技术是合理的,但是它需要一直到 IIS 的验证,以确保您在 Action 中设置的 HTTP 状态代码实际转发到浏览器。
@bzlm,我根本没有使用 GoDaddy。只是带有 Asp.net MVC 的 IIS。如果“http errorMode”未设置为“详细”,我仍然会收到 500 内部服务器错误。所以这似乎与IIS有关。无论如何,我非常感谢您研究我冗长的问题并就我的方法提供您的意见。干杯。
【参考方案1】:
IIS 7 中的新功能:如果您的 web.config 的 customErrors 设置为 on(或 remoteOnly 并且您是远程的),您必须将 HttpResponse.TrySkipIisCustomErrors 设置为 true 才能覆盖 IIS 的错误页面设置。请参阅this answer
【讨论】:
以上是关于与 ASP.net MVC 中 Ajax 请求中的错误处理有关的疑问的主要内容,如果未能解决你的问题,请参考以下文章
识别 ASP.NET MVC 代码中的 Angular js AJAX 调用
ASP.NET MVC 中的 ASP.NET AJAX 与 jQuery
使用 WIF 和 jquery ajax 请求时 ASP.NET MVC 3 中的会话 Cookie 过期处理