111

I am getting an error in an ajax call from jQuery.

Here is my jQuery function:

function DeleteItem(RecordId, UId, XmlName, ItemType, UserProfileId) {
    var obj = {
        RecordId: RecordId,
        UserId: UId,
        UserProfileId: UserProfileId,
        ItemType: ItemType,
        FileName: XmlName
    };
    var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);

    $.ajax({
        type: "POST",
        url: "EditUserProfile.aspx/DeleteRecord",
        data: json,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        async: true,
        cache: false,
        success: function(msg) {
            if (msg.d != null) {
                RefreshData(ItemType, msg.d);
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert("error occured during deleting");
        }
    });
}

and this is my WebMethod:

[WebMethod]
public static string DeleteRecord(Int64 RecordId, Int64 UserId, Int64 UserProfileId, string ItemType, string FileName) {
    try {
        string FilePath = HttpContext.Current.Server.MapPath(FileName);

        XDocument xmldoc = XDocument.Load(FilePath);
        XElement Xelm = xmldoc.Element("UserProfile");
        XElement parentElement = Xelm.XPathSelectElement(ItemType + "/Fields");

        (from BO in parentElement.Descendants("Record")
         where BO.Element("Id").Attribute("value").Value == RecordId.ToString()
         select BO).Remove();
        XDocument xdoc = XDocument.Parse(Xelm.ToString(), LoadOptions.PreserveWhitespace);
        xdoc.Save(FilePath);

        UserInfoHandler obj = new UserInfoHandler();
        return obj.GetHTML(UserId, UserProfileId, FileName, ItemType, RecordId, Xelm).ToString();
    } catch (Exception ex) {
        HandleException.LogError(ex, "EditUserProfile.aspx", "DeleteRecord");
    }
    return "success";
}

Can anybody please tell me what's wrong in my code?

I am getting this error:

{
    "Message":"Invalid JSON primitive: RecordId.",
    "StackTrace":"
       at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()
       at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
       at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)
       at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)
       at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)
       at System.Web.Script.Services.RestHandler.GetRawParamsFromPostRequest(HttpContext context, JavaScriptSerializer serializer)
       at System.Web.Script.Services.RestHandler.GetRawParams(WebServiceMethodData methodData, HttpContext context)
       at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)",
    "ExceptionType":"System.ArgumentException"
}
gunr2171
  • 16,104
  • 25
  • 61
  • 88
Radhi
  • 6,289
  • 15
  • 47
  • 68
  • What I don't understand is. The javascript is about AddAlbumToMyProfile while the WebMethod is called DeleteRecord. Are you sure you show us the right code pieces? – jitter Mar 15 '10 at 09:13
  • Any chance you can also capture what the POST looks like (using firebug or whatnot) and add it to the question? I'm not sure if it's the way you're encoding the data before sending it, but you could also try serializing it using this( http://www.json.org/json2.js ). – Roman Mar 21 '10 at 21:31

12 Answers12

144

Just a guess what does the variable json contain after

var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);?

If it is a valid json object like {"foo":"foovalue", "bar":"barvalue"} then jQuery might not send it as json data but instead serialize it to foor=foovalue&bar=barvalue thus you get the error "Invalid JSON primitive: foo"

Try instead setting the data as string

$.ajax({
    ...
    data: '{"foo":"foovalue", "bar":"barvalue"}', //note the additional quotation marks
    ...
})

This way jQuery should leave the data alone and send the string as is to the server which should allow ASP.NET to parse the json server side.

jitter
  • 53,475
  • 11
  • 111
  • 124
  • 8
    thanks for the clarification, add one more comment, you can always do like JSON.stringify({foo:'foovalue', bar:'barvalue'}) for a easier life – Elaine Jul 01 '18 at 12:26
  • 1
    A decade late to the party, but still relevant: that's not valid JSON. Strings (including property names) in JSON [must use double quotes](https://www.json.org/json-en.html), so it would have to be `{"foo": "foovalue", "bar": "barvalue"}`. Using single quotes is a syntax error. – Mike 'Pomax' Kamermans Mar 18 '20 at 17:48
116

Using

data : JSON.stringify(obj)

in the above situation would have worked I believe.

Note: You should add json2.js library all browsers don't support that JSON object (IE7-) Difference between json.js and json2.js

Community
  • 1
  • 1
Andrew
  • 3,650
  • 9
  • 31
  • 32
  • 3
    Thanks! When using simple JS classes this works. I changed `data: { JSON.stringify(obj) }` to `data: JSON.stringify(obj)` (My javascript/JSON class to serialize is of the style `var myObj = { title: "x", subclass = someVar, ... } `) – lko Sep 11 '12 at 07:58
  • 1
    Note that this is the solution provided you actually need to send JSON ([which you might with asp.net web services](https://stackoverflow.com/q/5690882/11683)). In other cases it might be easier to just [remove the `contentType`](https://stackoverflow.com/a/24598345/11683) and let jQuery pass the form-encoded data. – GSerg Oct 17 '17 at 07:30
22

it's working something like this

data: JSON.stringify({'id':x}),
Jessica Saenz
  • 221
  • 2
  • 2
  • 3
    This answer turned up in the low quality review queue, presumably because you don't provide any explanation of the code. If this code answers the question, consider adding adding some text explaining the code in your answer. This way, you are far more likely to get more upvotes — and help the questioner learn something new. – lmo Sep 07 '16 at 22:19
  • I want to pass two parameters: an array of complex object and an integer. I do it: data: {items: JSON.stringify(myarray), myId:value}. – A.Dara Mar 01 '17 at 09:07
19

As noted by jitter, the $.ajax function serializes any object/array used as the data parameter into a url-encoded format. Oddly enough, the dataType parameter only applies to the response from the server - and not to any data in the request.

After encountering the same problem I downloaded and used the jquery-json plugin to correctly encode the request data to the ScriptService. Then, used the $.toJSON function to encode the desired arguments to send to the server:

$.ajax({
    type: "POST",
    url: "EditUserProfile.aspx/DeleteRecord",
    data: $.toJSON(obj),
    contentType: "application/json; charset=utf-8",
    dataType: "json"
    ....
});
leepowers
  • 37,828
  • 23
  • 98
  • 129
  • 2
    thanks for pointing out that the `data` parameter is ignored by the call. – Zephyr was a Friend of Mine Sep 08 '11 at 16:19
  • 3
    This works, but changing `data: { JSON.stringify(obj) }` to `data: JSON.stringify(obj)` worked for me if your javascript class is of the style `var myObj = { title: "x", subclass = someVar, ... } ` thanks to the point about the data encoding. – lko Sep 11 '12 at 07:57
14

Jquery Ajax will default send the data as query string parameters form like:

RecordId=456&UserId=123

unless the processData option is set to false, in which case it will sent as object to the server.

  • contentType option is for the server that in which format client has sent the data.

  • dataType option is for the server which tells that what type of data client is expecting back from the server.

Don't specify contentType so that server will parse them as query String parameters not as json.

OR

Use contentType as 'application/json; charset=utf-8' and use JSON.stringify(object) so that server would be able to deserialize json from string.

T Gupta
  • 947
  • 11
  • 11
6

I guess @jitter was right in his guess, but his solution didn't work for me.

Here is what it did work:

$.ajax({
    ...
    data: "{ intFoo: " + intFoo + " }",
    ...
});

I haven't tried but i think if the parametter is a string it should be like this:

$.ajax({
    ...
    data: "{ intFoo: " + intFoo + ", strBar: '" + strBar + "' }",
    ...
});
Diego
  • 16,436
  • 26
  • 84
  • 136
  • 9
    If I had to write code like that (string concat) to create JSON objects, I would kill myself (figuratively speaking). There has to be a better way. – PandaWood Feb 20 '13 at 23:32
4

I was facing the same issue, what i came with good solution is as below:

Try this...

$.ajax({
    type: "POST",
    url: "EditUserProfile.aspx/DeleteRecord",
    data: '{RecordId: ' + RecordId + ', UserId: ' + UId + ', UserProfileId:' + UserProfileId + ', ItemType: \'' + ItemType + '\', FileName: '\' + XmlName + '\'}',
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    async: true,
    cache: false,
    success: function(msg) {
        if (msg.d != null) {
            RefreshData(ItemType, msg.d);
        }
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert("error occured during deleting");
    }
});

Please note here for string type parameter i have used (\') escape sequence character for denoting it as string value.

Sohel Pathan
  • 367
  • 3
  • 13
2

Here dataTpe is "json" so, data/reqParam must be in the form of string while calling API, many as much as object as you want but at last inside $.ajax's data stringify the object.

             let person= {  name: 'john',
                age: 22
            };

           var personStr = JSON.stringify(person); 

            $.ajax({
                url: "@Url.Action("METHOD", "CONTROLLER")",
                type: "POST",
                data: JSON.stringify( { param1: personStr } ),
                contentType: "application/json;charset=utf-8",
                dataType: "json",
        success: function (response) {

            console.log("Success");

        },
        error: function (error) {
            console.log("error found",error);
        }
    });

OR,

       $.ajax({
                url: "@Url.Action("METHOD", "CONTROLLER")",
                type: "POST",
                data: personStr,
                contentType: "application/json;charset=utf-8",
                dataType: "json",
        success: function (response) {

            console.log("Success");

        },
        error: function (error) {
            console.log("error found",error);
        }
    });
1

If manually formatting JSON, there is a very handy validator here: jsonlint.com

Use double quotes instead of single quotes:

Invalid:

{
    'project': 'a2ab6ef4-1a8c-40cd-b561-2112b6baffd6',
    'franchise': '110bcca5-cc74-416a-9e2a-f90a8c5f63a0'
}

Valid:

{
    "project": "a2ab6ef4-1a8c-40cd-b561-2112b6baffd6",
    "franchise": "18e899f6-dd71-41b7-8c45-5dc0919679ef"
}
Michael
  • 8,362
  • 6
  • 61
  • 88
Daniel de Zwaan
  • 3,064
  • 25
  • 24
0

I had the same issue. I was calling parent page "Save" from Popup window Close. Found that I was using ClientIDMode="Static" on both parent and popup page with same control id. Removing ClientIDMode="Static" from one of the pages solved the issue.

TylerH
  • 20,799
  • 66
  • 75
  • 101
0

On the Server, to Serialize/Deserialize json to custom objects:

public static string Serialize<T>(T obj)
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    MemoryStream ms = new MemoryStream();
    serializer.WriteObject(ms, obj);
    string retVal = Encoding.UTF8.GetString(ms.ToArray());
    return retVal;
}

public static T Deserialize<T>(string json)
{
    T obj = Activator.CreateInstance<T>();
    MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    obj = (T)serializer.ReadObject(ms);
    ms.Close();
    return obj;
}
Ioannis Suarez
  • 587
  • 6
  • 5
-2

these answers just had me bouncing back and forth between invalid parameter and missing parameter.

this worked for me , just wrap string variables in quotes...

data: { RecordId: RecordId,
            UserId: UId,
            UserProfileId: UserProfileId,
            ItemType: '"' +  ItemType + '"',
            FileName: '"' +  XmlName + '"'
    }
vernmic
  • 25
  • 5