When performing post via ajax, Bad Request is returned instead of the JSON result

末鹿安然 提交于 2019-11-29 23:03:34
aravind

Think this is an issue with IIS trying to use custom error response rather sending the error message that the controller is generating.

<system.webServer>
    ...
    <httpErrors existingResponse="PassThrough"></httpErrors>
    ...
</system.webServer>

Or

Response.TrySkipIisCustomErrors = true;

Reference - https://stackoverflow.com/a/4029197/1304559

Check out this blog post http://weblog.west-wind.com/posts/2009/Apr/29/IIS-7-Error-Pages-taking-over-500-Errors

Since response code is set to 400, IIS replaces your content with its custom error page content

The issue I am seeing is that your trying to set the encoding of the JSON to UTF-8. Normally it works just fine, however, on IIS, it has a custom error to report that the UTF-8 is not necessary.

Few other things to note. You are doing a POST, so the server will be expecting a json file. If provided none, it will not know what to do.

o.v.

Your response comes back with Content-Type: text/html http header, but it should be application/json. This is not an issue in Chrome (and you don't get mismatch warnings in the console) because you're relying on overrideMimeType... which, you guessed it, is not IE-friendly. In fact, the following is never executed on older versions of IE:

if (x && x.overrideMimeType) {
  return x.overrideMimeType("application/json;charset=UTF-8");
}

Your solution could be to make sure the content is served with correct content type. If you're familiar with tampering tools like Burp Suite, you could add the correct header on-the-fly and see if that fixes the problem. I would probably avoid inlining methods like AddHeader and see if there is a way this can be fixed at a higher - routing, perhaps - level.

I have filled in a fail test that should help.

$.post($frm.attr("action"), ko.mapping.toJSON(data, map))
.done(function (dataVal) {
    //process dataVal
    var mystruct = GenerateCache($.parseJSON(dataVal));
})
.fail(function (jqxhr, textStatus, error) {
    if (jqxhr.responseText.indexOf("YourMoniker") != -1) {
        parseData($.parseJSON(jqxhr.responseText));
    } else {
        var err = textStatus + ', ' + error;
        console.log("Request Failed: " + err);
    }
});


function GenerateCache(data) {
    var obj = function () { };
    obj.prototype = data;
    return new obj();
}

Specifically look at the error handling in the .fail section.

It's not your controller, that's working fine. You're missing a required field: both IE and Chrome are returning status code 400 Bad Request - but only Chrome is properly processing the responseText and giving you [{"Name":"Nome","ErrorMessage":"campo obrigatório."}] meaning you have a missing form field.

Although I've searched all over and haven't found any reference to specific IE bugs in processing XMLHttpRequest.responseText with non-200 status codes, it looks like IE is replacing your response body with its own:

Headers (Response)

HTTP/1.1 400 Bad Request
...
Content-Length: 11

Bad Request

Indicates that the "content" as it treats it is the "Bad Request" status text, not the proper json response (which Chrome reads as content-length 54, for instance). This might mean IE is discarding your response body (I doubt it, that'd be bloody incredible) or it just isn't be processed "properly." Try dumping the rest of your jqXHR object and the arguments for your fail handler to see if you can find it in there somewhere.

IE (all versions, including IE11) will put "Bad Request" in the status text and ignore the JSON you put in as the message.

In order to use the xhr.responseText in IE on error, you need to throw an exception instead of returning a Json or JsonResult with HttpStatusCode.BadRequest;

So... before:

Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(new { Message = "There is already a distribution set which covers part or all of this period" });

This works in Chrome, FF and any sane browser, really. After:

throw new Exception("You have posted invalid datas.");

As an unhandled exception, it will be passed to the browser as a response, this will work in Chrome, FF and even in IE. It is not graceful, same as all unhandled exceptions (or just exceptions, for that matter), but it will do the job of letting you receive an appropriate response.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!