Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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 worksaround 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.

regards, Nirvan.

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 ?

share|improve this question
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. – Nirvan Sep 18 '11 at 11:33
@bzlm, here is where I found the solution. bala-krishna.com/… – Nirvan 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. – Nirvan Sep 18 '11 at 13:56
show 5 more comments

1 Answer

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.

share|improve this answer
But your OnError would still run as long as the response from the server was actually 500, regardless of whether the error page (which wouldn't be displayed anyway, right?) was the default one or the detailed one. I'm assuming this means the response wasn't 500 for the default error page. Is that right? – bzlm Sep 22 '11 at 15:56
@bzlm, The OnError runs, but its about what comes from the server as response when response code is set to 500 in my controller. The IIS replaces its own 500 Internal Server Response instead of the one (PartialView) that I am returning to the browser. This can only be prevented if I set errorMode to Detailed. But then if my module fail with 500 status code, then because of errorMode set to Detailed a detailed response (which shows the part of code that failed) is sent from the server. I want to send Partial View if I set response code 500 and default IIS page for any code error – Nirvan Sep 23 '11 at 0:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.