6

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.

Gordon
  • 312,688
  • 75
  • 539
  • 559
Jatin
  • 4,023
  • 10
  • 60
  • 107
  • Strange that detailed error pages would solve your problem. Do you mean that the whole page was replaced by the error screen, rather than the content div? Did that also update the current URL in the browser? That sounds more like the AJAX call itself failed, because it should never result in a normal GET/POST - it should only render via JS. I think your technique is acceptable since you can never protect against 500s from AJAX calls *anyway* - `OnError` should be sufficient to handle them. I think you should dig up the cause of `OnError` not working in the deployed environment first. – bzlm Sep 18 '11 at 10:46
  • @bzlm, I am pretty sure that the browser neglected the whole response that I returned from controller for the given ajax request when I set the response status to 500. Somehow, the browser displayed its own "500 Internal Server Error" screen instead. But you were right that only the content div's content was replaced by the "500 Internal Server Error" Page. The other portions of my html page remained as before. But still, I had to prevent browser from poping its error page and indeed the "errorMode" solved the issue. I didn't change anything else in my application (as far as I know). Thanks. – Jatin Sep 18 '11 at 11:33
  • @bzlm, here is where I found the solution. http://www.bala-krishna.com/how-to-disable-500-internal-server-error-on-godaddy-windows-hosting/ – Jatin Sep 18 '11 at 11:37
  • I see. It sounds like GoDaddy doesn't actually return a HTTP status code of 500 to the browser, since your `OnError` handler didn't fire. I'm guessing they use a base Web.config or IIS setting that gets overridden by the `httpErrors errorMode` with the side-effect that the response code is actually 500. All in all, I'd say that your technique is sound, but that it requires verification all they way down to IIS to ensure that the HTTP status code you set in the Action is actually forwarded to the browser. – bzlm Sep 18 '11 at 13:45
  • @bzlm, I am not using GoDaddy at all. Just IIS with Asp.net MVC. Still I am presented with the 500 Internal Server Error if "http errorMode" is not set to "Detailed". So this seems to be related to IIS. Anyway, I am very grateful to you for studying my lengthy question and providing your opinion about my approach. Cheers. – Jatin Sep 18 '11 at 13:56
  • Check with Fiddler what the response code is on the Action that returns a 500. – bzlm Sep 18 '11 at 14:31
  • Hmm. I don't have Fiddler installed on my test machine right now. So it will be a while that I install it and see what status code actually gets returned for the response. Will let you know about the same. – Jatin Sep 18 '11 at 14:34
  • I still think it should've worked with the default error page, whichever that is. See my comment. – bzlm Sep 22 '11 at 15:56
  • possible duplicate of [Detailed 500 error message, ASP + IIS 7.5](http://stackoverflow.com/questions/2640526/detailed-500-error-message-asp-iis-7-5) – bzlm Sep 23 '11 at 09:53

1 Answers1

0

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

Community
  • 1
  • 1
Carl G
  • 17,394
  • 14
  • 91
  • 115