关于ASP.net MVC中Ajax请求中的错误处理的疑问

发布于 2024-12-05 05:17:26 字数 2645 浏览 1 评论 0原文

几天来,我一直在使用 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" alt="loading" 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”处理程序() 被调用。这是我如何在控制器中执行此操作的片段。

[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 内部服务器错误”屏幕。所以我有几个疑惑导致我昨晚睡不好。

  1. 我用于 Ajax 编辑的方法合理吗?如果不是,我可以通过其他方式处理 Ajax 编辑(能够显示模型错误)。

  2. 由于我开发这些模块已经有几天了,并且付出了相当大的努力,是否有任何解决方法可以让它在 XP 机器上工作。基本上,如果我能以某种方式阻止浏览器显示默认的“500 内部服务器错误”屏幕,那就太理想了。

  3. 此方法是否适用于 Windows 7,因为我在用于浏览网站的同一台 Windows 7 计算机上安装了 IIS 7,或者只是它适用于 Windows 7。

如果有任何其他建议,请继续。

编辑: 我已经找到了解决我的问题的方法。所以这意味着疑问 2 和 3 都没有得到解答。基本上,web.config 中的以下条目会阻止浏览器显示网站的默认浏览器页面。

  <system.webServer>
      <httpErrors errorMode="Detailed"/>
  </system.webServer>

但这仍然消除了我的第一个疑问。我是否使用了合理的 Ajax 编辑方法?


我用 fiddler 检查了响应,发现是 IIS 发送了服务器错误 500 的默认错误页面。因此需要将其配置为返回“详细”响应。我们可以使用 IIS 管理器来完成此操作。我遵循的另一个选项是在应用程序的 web.config 文件中的应用程序级别定义它。

然而,我再次陷入两难境地:是采用这种方法还是重新设计我的整个应用程序。出现的问题是,如果确实有某个模块因 500 Internal Server 而失败,则我的代码会在浏览器中公开,因为 errorMode 设置为“详细”。因此,当我将响应错误代码设置为 500 时,如果应用程序的任何其他部分失败(我不是设置 500 状态代码的人),那么我需要某种方法来提供自定义响应,则应发送默认错误页面,而不是公开我的代码通过“详细”回应。请提供任何帮助。

问候, 尼尔凡。

I have been developing a web application on my local machine for some days now using Visual Studio 2010. Last night I deployed my application on IIS 7 and frustratingly stumbled across a major show stopper. The problem is related to error handling in Ajax request. To begin with I have some edit screens which works on ajax request. Here is the what the ajax part of the Ajax edit screen looks like.

@using (Ajax.BeginForm("_CityEdit", null, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "content", 
                                                            LoadingElementId="imgSaveLoading", OnFailure="onError",
                                                            OnSuccess = "onSuccess" }, new { id = "frmCity" })) {
    <img id="imgSaveLoading" alt="loading" 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 -->
}

I was relying on the "onError" callback of the above Ajax.BeginForm(). So in my controller, whenever I wanted to display error to user (model error or any other error), I just set the Server Response to 500 (Internal Server Error) optimistically hoping that this would result in "OnError" handler of Ajax.BeginForm() being invoked. Here is a snippet of how I did this in my controller.

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

As can be seen from above code, I returned PartialView and if it contained Model Errors, they will automatically get displayed on the Ajax Edit Screen. Then in the "OnError" JavaScript I just replace the related div with the PartialView returned by the controller something like this.

function onError(xhr) {
    $('#content').html(xhr.responseText);
}

This all worked great on my development machine. When I deployed my application on IIS 7 and accessed it from an windows XP box (with IE 8 or Chrome), instead of PartialView, the browsers just displayed the default "500 Internal Server Error" screen. So I have a few doubts that caused me not to sleep well last night.

  1. Is the approach that I have used for Ajax editing a reasonable one. If not what could be the other way(s) I could have handled Ajax Editing (with ability to display model errors).

  2. Since I been developing these modules for some days now and have put up considerable effort, is there any work arounds to get it working on XP box. Basically, it would be ideal if I could somehow prevent browser from displaying their default "500 Internal Server Error" screen.

  3. Is this approach working on windows 7, because I have IIS 7 installed on the same windows 7 machine that I am using to browse to site, or its just that it works well with windows 7.

If any other suggestions, please go ahead.

Edit:
I have found the workaround for my problem. So that means doubt no 2 and 3 are answered. Basically the following entry in web.config prevents the browser from showing up default browser pages for the website.

  <system.webServer>
      <httpErrors errorMode="Detailed"/>
  </system.webServer>

But that still leaves out my first doubt. Have I used a reasonable approach to Ajax editing ?


I checked the response with the fiddler and it was IIS that was sending default error page for the Server error 500. So it needs to be configured to return "Detailed" response. We can do this using the IIS manager. Another option that I was following is to define it at application level in application's web.config file.

However, I am again in a dilemma whether to go with this approach or to rework my whole application. The problem that occurs is that if there is really some module failing with 500 Internal Server, my code gets exposed in the browser as the errorMode is set to "Detailed". So I need some way to provide my custom response when I set response error code to 500 and if any other part of application fails (I am not the one setting 500 status code) then the default error page should be sent instead of exposing my code through "Detailed" response. Any help please.

regards,
NIrvan.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

世俗缘 2024-12-12 05:17:26

New in IIS 7: you must set HttpResponse.TrySkipIisCustomErrors to true in order to override IIS's Error Pages settings if your web.config's customErrors are set to on (or remoteOnly and you are remote.) See this answer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文