Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery.post() returns 200 OK from MVC 4 WebAPI, but error-handler is hit

I've got an odd case where my jquery.post returns a code #200 (OK) but the error-handler is hit.

This is my MVC WebAPI serverside code (all it does is returning code #200 OK):

[HttpPost]
public HttpResponseMessage Post(T input)
{
    //_handler.Create(input);

    return Request.CreateResponse(HttpStatusCode.OK);
}

and this is my client script

ServerAccess.prototype.Save = function (m) {

            $.post("http://localhost:55482/M/", m)
            .success(
                function (o) {
                    alert("success");
                })
            .error(
                function (xhr, textStatus, errorThrown) {
                    if (typeof console == 'object' && typeof console.log == 'function') {
                        console.log(xhr);
                        console.log(textStatus);
                        console.log(errorThrown);
                    }
                }
            );
        };

The console output in Firebug is:

POST http://localhost:55482/M/ 200 OK 894ms

Headers


Response Headers

Content-Length 6

Content-Type application/json; charset=utf-8

Date Sun, 28 Oct 2012 18:55:17 GMT

Server Microsoft-HTTPAPI/2.0


Request Headers

Accept /

Accept-Encoding gzip, deflate

Accept-Language nb-no,nb;q=0.9,no-no;q=0.8,no;q=0.6,nn-no;q=0.5,nn;q=0.4,en-us;q=0.3,en;q=0.1

Connection keep-alive

Content-Length 21

Content-Type application/x-www-form-urlencoded; charset=UTF-8

Host localhost:55482

Origin null

User-Agent Mozilla/5.0 (Windows NT 6.2; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0

and

Object { readyState=0, status=0, statusText="error"}

error

(an empty string)

I've browsed around and seen others had similar problems, usually malformed JSON in the response. Since I only return a 200 OK an no content this doesn't seem to fit my case. However I did try to return a empty object like so

var o = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(new T());

return Request.CreateResponse(HttpStatusCode.OK, o);

The serverside runs from Visual Studio 2012, and the client is just a standalone .html with some .js files. Also, with a breakpoint in VS I know the request is received by the server, and with Postman for Chrome everyting works great.

So the question is of course: what am I doing wrong here? Why is the error-handler hit?

Thanks!

like image 202
Andreas Avatar asked Oct 28 '12 19:10

Andreas


1 Answers

Try this instead:

ServerAccess.prototype.Save = function (m) {
    $.ajax({
        "type": "POST",
        "url": "http://localhost:55482/M/",
        "data": m,
        "dataType": "json",
        "success": function (data, textStatus, xhr) {
            alert("success");
        },
        "error": function (xhr, textStatus, errorThrown) {
            if (typeof console === 'object' && typeof console.log === 'function') {
                console.log(xhr);
                console.log(textStatus);
                console.log(errorThrown);
            }
        }
    });
};

This allows you to set an expected return MIME type of application/json.

UPDATE

If you're running your standalone HTML page on http://localhost:55482, then it won't be cross-domain. If you're running it on file:///C:/Users/.../Desktop/test.htm or somewhere else, then it will be a cross-domain request. http versus https: also makes the difference.

A jsonp request is a GET request and cannot be a POST. This is because jsonp requests are implemented by adding a <script> element to the page with the source set to your url, with data appended to the querystring (plus a timestamp parameter). Any POST requests that expect a jsonp return should be automatically converted to GET requests.

Finally, since your routine expects data back, you'll need to return some actual data as jQuery will try to parse the JSON that's returned into an object (which it cannot do if no data is returned) and will throw an error if the data cannot be parsed.

Try changing your response message to:

String o = "success";
System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();

return Request.CreateResponse(HttpStatusCode.OK, ser.Serialize(o));
like image 125
pete Avatar answered Jan 05 '23 00:01

pete