与 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 过期处理

ASP.NET Core MVC 使用 api +javascript 客户端与 ajax

ASP.NET MVC 实现AJAX跨域请求方法《1》

如何在 ASP.NET MVC 中进行长轮询 AJAX 请求? [复制]