265

I am trying to post a JSON object to a asp.net webservice.

My json looks like this:

var markers = { "markers": [
  { "position": "128.3657142857143", "markerPosition": "7" },
  { "position": "235.1944023323615", "markerPosition": "19" },
  { "position": "42.5978231292517", "markerPosition": "-3" }
]};

I am using the json2.js to stringyfy my JSON object.

and I am using jquery to post it to my webservice.

  $.ajax({
        type: "POST",
        url: "/webservices/PodcastService.asmx/CreateMarkers",
        data: markers,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(data){alert(data);},
        failure: function(errMsg) {
            alert(errMsg);
        }
  });

I am getting the following error:

Invalid JSON primitive

I have found a bunch of posts relating to this and it seems to be a really common problem but nothing i try fixes the issue.

When firebug what is being posted to the server it looks like this:

markers%5B0%5D%5Bposition%5D=128.3657142857143&markers%5B0%5D%5BmarkerPosition%5D=7&markers%5B1%5D%5Bposition%5D=235.1944023323615&markers%5B1%5D%5BmarkerPosition%5D=19&markers%5B2%5D%5Bposition%5D=42.5978231292517&markers%5B2%5D%5BmarkerPosition%5D=-3

My webservice function that is being called is:

[WebMethod]
public string CreateMarkers(string markerArray)
{
    return "received markers";
}
Syscall
  • 19,327
  • 10
  • 37
  • 52
Code Pharaoh
  • 3,044
  • 2
  • 22
  • 26
  • 'failure' is not provided as a possible setting amongst those listed in http://api.jquery.com/jQuery.ajax/ ...maybe you mistaken it with 'error' instead? – danicotra Nov 02 '13 at 14:32

5 Answers5

439

You mentioned using json2.js to stringify your data, but the POSTed data appears to be URLEncoded JSON You may have already seen it, but this post about the invalid JSON primitive covers why the JSON is being URLEncoded.

I'd advise against passing a raw, manually-serialized JSON string into your method. ASP.NET is going to automatically JSON deserialize the request's POST data, so if you're manually serializing and sending a JSON string to ASP.NET, you'll actually end up having to JSON serialize your JSON serialized string.

I'd suggest something more along these lines:

var markers = [{ "position": "128.3657142857143", "markerPosition": "7" },
               { "position": "235.1944023323615", "markerPosition": "19" },
               { "position": "42.5978231292517", "markerPosition": "-3" }];

$.ajax({
    type: "POST",
    url: "/webservices/PodcastService.asmx/CreateMarkers",
    // The key needs to match your method's input parameter (case-sensitive).
    data: JSON.stringify({ Markers: markers }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data){alert(data);},
    error: function(errMsg) {
        alert(errMsg);
    }
});

The key to avoiding the invalid JSON primitive issue is to pass jQuery a JSON string for the data parameter, not a JavaScript object, so that jQuery doesn't attempt to URLEncode your data.

On the server-side, match your method's input parameters to the shape of the data you're passing in:

public class Marker
{
  public decimal position { get; set; }
  public int markerPosition { get; set; }
}

[WebMethod]
public string CreateMarkers(List<Marker> Markers)
{
  return "Received " + Markers.Count + " markers.";
}

You can also accept an array, like Marker[] Markers, if you prefer. The deserializer that ASMX ScriptServices uses (JavaScriptSerializer) is pretty flexible, and will do what it can to convert your input data into the server-side type you specify.

Rune Kaagaard
  • 6,643
  • 2
  • 38
  • 29
Dave Ward
  • 59,815
  • 13
  • 117
  • 134
  • 4
    You wrote "so that jQuery doesn't attempt to URLEncode your data.", but it is not correct. To stop jquery from urlencoding your data you must set processData to false. – Softlion Oct 20 '11 at 08:58
  • 8
    Passing in a string is enough to prevent jQuery from URLEncoding the data parameter. You can set processData to false, but it's superfluous (and doing that alone, without passing in a JSON string for the data, isn't enough). – Dave Ward Oct 20 '11 at 16:16
  • 1
    This same issue (and answer) applies to Rails as well. – GregT Jan 30 '13 at 00:02
  • 2
    @DaveWard Does `contentType` is considered if we use GET and not POST ? – Royi Namir Jul 18 '13 at 13:34
  • @RoyiNamir If you're using ASMX ScriptServices or ASPX WebMethods, you need to use POST in order to get them to return JSON. If you GET, Content-Type correct or not, you'll get XML instead. – Dave Ward Jul 18 '13 at 20:57
  • @DaveWard I just can't find the 'failure' setting listed in http://api.jquery.com/jQuery.ajax/ I think the answerer mistaken it with 'error' instead – danicotra Nov 02 '13 at 14:30
  • With ASP.NET Web API it appears that the Markers key (the extra level of JSON hierarchy) should not be used (although I didn't try it with a collection parameter). Thank you - your answer resolved hours of trial and error! – TrueWill Dec 07 '13 at 17:44
  • Do I have to do JSON.??stringify Since from above I can clearly see that it is in JSON format – Hitesh Apr 19 '14 at 07:48
  • @hitesh: `markers` is an object literal until you use `JSON.stringify` on it, not JSON. If you pass jQuery an object literal as the data parameter to `$.ajax`, it sends the data as a URL encoded string, not a JSON string. – Dave Ward Apr 19 '14 at 17:28
  • Dave, your links to `encosia.com` are currently reported by Chrome as distributing malware. – Eduard Wirch Mar 18 '17 at 20:55
  • After completing a CAPTCHA challenge at Cloudflare, Encosia is giving me "Error 522 - Connection timed out". – halfer Jan 28 '18 at 20:28
  • 1
    Use `file_get_contents('php://input')` to get your `json` data in `php`. – n1nsa1d00 Mar 22 '18 at 14:39
  • This Did not Work For me . i tried Your Code but The Parameters is Null on Server Side . and i get Null Reference Error . @DaveWard – Iman Estiri Mar 30 '21 at 10:06
  • not working with headers: { 'X-Requested-With': 'XMLHttpRequest' }, – jhenya-d Dec 30 '21 at 09:14
  • Great answer, your inclusion of the server-side parameters helped me a lot, thanks. – Lazlow Jan 06 '23 at 12:52
22
  1. markers is not a JSON object. It is a normal JavaScript object.
  2. Read about the data: option:

    Data to be sent to the server. It is converted to a query string, if not already a string.

If you want to send the data as JSON, you have to encode it first:

data: {markers: JSON.stringify(markers)}

jQuery does not convert objects or arrays to JSON automatically.


But I assume the error message comes from interpreting the response of the service. The text you send back is not JSON. JSON strings have to be enclosed in double quotes. So you'd have to do:

return "\"received markers\"";

I'm not sure if your actual problem is sending or receiving the data.

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Thanks for you help Felix, I thought that by running markers through the JSON.stringyfy method i was converting it to a query string, I have done as you suggested but unfortunatly it does not work I am not posting the following. – Code Pharaoh Jun 12 '11 at 17:33
  • markers=%7B%22markers%22%3A%5B%7B%22position%22%3A%22128.3657142857143%22%2C%22markerPosition%22%3A%227%22%7D%2C%7B%22position%22%3A%22235.1944023323615%22%2C%22markerPosition%22%3A%2219%22%7D%2C%7B%22position%22%3A%2242.5978231292517%22%2C%22markerPosition%22%3A%22-3%22%7D%5D%7D – Code Pharaoh Jun 12 '11 at 17:33
  • @Dreamguts: It is a bit unclear to me what you want. Do you want to send `markers` as JSON string? – Felix Kling Jun 12 '11 at 17:34
  • Hi Felix, yes i want to send the markers object as a JSON string so that i can use it in my webservice. – Code Pharaoh Jun 12 '11 at 17:35
  • @Dreamguts: Then it should work this way. Also the "code" you posted in the comment looks ok. Of course you have to decode it properly on the server side and maybe you have to change the name of the parameter, I don't know. – Felix Kling Jun 12 '11 at 17:37
  • just read your edit and i am pretty sure that it is the markers string that is causing the error as i get "Invalid JSON primitive: markers. – Code Pharaoh Jun 12 '11 at 17:37
  • @Dreamguts: Maybe you need: `data: {markers: JSON.stringify(markers.markers)}` – Felix Kling Jun 12 '11 at 17:38
  • @Felix Kling: yeah i thought that too but doesnt seem to have worked. – Code Pharaoh Jun 12 '11 at 17:42
  • @Dreamguts: Well, I cannot say more without more information. Unfortunately I have no experience with asp.net. – Felix Kling Jun 12 '11 at 17:42
6

I tried Dave Ward's solution. The data part was not being sent from the browser in the payload part of the post request as the contentType is set to "application/json". Once I removed this line everything worked great.

var markers = [{ "position": "128.3657142857143", "markerPosition": "7" },

               { "position": "235.1944023323615", "markerPosition": "19" },

               { "position": "42.5978231292517", "markerPosition": "-3" }];

$.ajax({

    type: "POST",
    url: "/webservices/PodcastService.asmx/CreateMarkers",
    // The key needs to match your method's input parameter (case-sensitive).
    data: JSON.stringify({ Markers: markers }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data){alert(data);},
    failure: function(errMsg) {
        alert(errMsg);
    }
});
araknoid
  • 3,065
  • 5
  • 33
  • 35
Usha
  • 374
  • 1
  • 5
  • 14
  • I am working with a server, I don't have access to. I removed contentType, it helped. But the payload was passing with and without it. Something else changed. The contentType changed to "application/x-www-form-urlencoded", which is wrong, but it works. Magic. Thanks. – sekrett Jul 05 '21 at 10:36
2

I have encountered this one too and this is my solution.

If you are encountering an invalid json object exception when parsing data, even though you know that your json string is correct, stringify the data you received in your ajax code before parsing it to JSON:

$.post(CONTEXT+"servlet/capture",{
        yesTransactionId : yesTransactionId, 
        productOfferId : productOfferId
        },
        function(data){
            try{
                var trimData = $.trim(JSON.stringify(data));
                var obj      = $.parseJSON(trimData);
                if(obj.success == 'true'){ 
                    //some codes ...
Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
-2

Please follow this to by ajax call to webservice of java var param = { feildName: feildValue }; JSON.stringify({data : param})

$.ajax({
            dataType    : 'json',
            type        : 'POST',
            contentType : 'application/json',
            url         : '<%=request.getContextPath()%>/rest/priceGroups',
            data        : JSON.stringify({data : param}),
            success     : function(res) {
                if(res.success == true){
                    $('#alertMessage').html('Successfully price group created.').addClass('alert alert-success fade in');
                    $('#alertMessage').removeClass('alert-danger alert-info');
                    initPriceGroupsList();
                    priceGroupId = 0;
                    resetForm();                                                                    
                }else{                          
                    $('#alertMessage').html(res.message).addClass('alert alert-danger fade in');
                }
                $('#alertMessage').alert();         
                window.setTimeout(function() { 
                    $('#alertMessage').removeClass('in');
                    document.getElementById('message').style.display = 'none';
                }, 5000);
            }
        });