Ajax处理中的“无效的JSON原语”


101

我在jQuery的ajax调用中遇到错误。

这是我的jQuery函数:

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");
        }
    });
}

这是我的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";
}

有人可以告诉我我的代码有什么问题吗?

我收到此错误:

{
    "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"
}

我不明白的是。javascript有关AddAlbumToMyProfile,而WebMethod称为DeleteRecord。您确定要向我们展示正确的代码段吗?
抖动

您是否也有可能捕获POST的外观(使用firebug或whatnot)并将其添加到问题中?我不确定这是否是在发送数据之前对数据进行编码的方式,但是您也可以尝试使用this(json.org/json2.js)进行序列化。
R0MANARMY

Answers:


135

只是猜测变量json之后包含什么

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

如果它是一个有效的json对象,{'foo':'foovalue', 'bar':'barvalue'}那么jQuery可能不会将其作为json数据发送,而是将其序列化为,foor=foovalue&bar=barvalue因此您会收到错误消息"Invalid JSON primitive: foo"

尝试改为将数据设置为字符串

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

这样,jQuery应该不理会数据并将字符串原样发送到服务器,这应允许ASP.NET解析json服务器端。


5
感谢您的澄清,再添加一条评论,您始终可以像JSON.stringify({foo:'foovalue',bar:'barvalue'})一样轻松生活
Elaine

派对晚了十年,但仍然有意义:这不是有效的JSON。JSON中的字符串(包括属性名称)必须使用双引号引起来,因此必须为{"foo": "foovalue", "bar": "barvalue"}。使用单引号是一种语法错误。
Mike'Pomax'Kamermans

108

使用

data : JSON.stringify(obj)

在上述情况下,我相信会奏效。

注意:您应该添加json2.js库,所有浏览器都不支持该JSON对象(IE7-) 。json.js和json2.js之间的区别


3
谢谢!使用简单的JS类时,此方法有效。我更改data: { JSON.stringify(obj) }data: JSON.stringify(obj)(要序列化的我的javascript / JSON类是这种样式var myObj = { title: "x", subclass = someVar, ... }
lko 2012年

1
请注意,这是您实际需要发送JSON的解决方案(您可能使用asp.net Web服务发送)。在其他情况下,只需删除contentType并让jQuery传递表单编码的数据可能会更容易。
Gserg

19

正如抖动所指出的,该$.ajax函数会将用作data参数的任何对象/数组序列化为url编码格式。奇怪的是,该dataType参数仅适用于服务器的响应,而不适用于请求中的任何数据。

遇到相同的问题后,我下载并使用了jquery-json插件将请求数据正确编码为ScriptService。然后,使用该$.toJSON函数对所需的参数进行编码以发送到服务器:

$.ajax({
    type: "POST",
    url: "EditUserProfile.aspx/DeleteRecord",
    data: $.toJSON(obj),
    contentType: "application/json; charset=utf-8",
    dataType: "json"
    ....
});

2
感谢您指出data调用会忽略该参数。
Noel Abrahams

3
此作品,但改变data: { JSON.stringify(obj) }data: JSON.stringify(obj),如果你的JavaScript类是风格的为我工作var myObj = { title: "x", subclass = someVar, ... } 由于有关数据编码的地步。
lko 2012年

19

它正在像这样工作

data: JSON.stringify({'id':x}),

3
这个答案出现在低质量的审阅队列中,大概是因为您没有提供任何代码说明。如果此代码回答了问题,请考虑在回答中添加一些解释该代码的文本。这样,您更有可能获得更多的赞誉-并帮助提问者学习新的知识。
lmo

我想传递两个参数:复杂对象数组和整数。我做到了:数据:{items:JSON.stringify(myarray),myId:值}。
A.Dara

感谢您发布答案。这对我有用。
ZMAX

13

jQuery Ajax将默认以查询字符串参数形式发送数据,例如:

RecordId=456&UserId=123

除非该processData选项设置为false,否则它将作为对象发送到服务器。

  • contentType 该选项用于客户机以其格式发送数据的服务器。

  • dataType 选项用于服务器,它告诉客户端期望从服务器返回哪种类型的数据。

不要指定contentType,以便服务器将它们解析为查询字符串参数,而不是json。

要么

使用contentType作为'application / json; charset = utf-8'并使用JSON.stringify(object),以便服务器能够从字符串中反序列化json。


5

我猜@jitter正确,但他的解决方案对我不起作用。

这是它的工作原理:

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

我没有尝试过,但我认为如果参数是字符串,则应该像这样:

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

9
如果必须编写这样的代码(字符串concat)来创建JSON对象,那么我会自杀(象征性地讲)。一定有更好的方法。
PandaWood

3

我面临着同样的问题,下面提供了一个好的解决方案:

试试这个...

$.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");
    }
});

请注意此处的字符串类型参数,我已使用(\')转义序列字符将其表示为字符串值。


数据:“ {Notes:\”“ + $('#txtNotes')。val()+” \“}
bestinamir

1

如果手动格式化JSON,则这里有一个非常方便的验证器:jsonlint.com

使用双引号而不是单引号:

无效:

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

有效:

{
    "project": "a2ab6ef4-1a8c-40cd-b561-2112b6baffd6",
    "franchise": "18e899f6-dd71-41b7-8c45-5dc0919679ef"
}

0

在服务器上,要将JSON序列化/反序列化为自定义对象:

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;
}

0

我遇到过同样的问题。我从弹出窗口“关闭”中将父页面称为“保存”。发现我ClientIDMode="Static"在父页面和弹出页面上使用的控件ID相同。ClientIDMode="Static"从其中一个页面中删除可以解决此问题。


0

这里的dataTpe是“ json”,因此,在调用API时,data / reqParam必须为字符串形式,其数量与您想要的对象一样多,但是最后$ .ajax的数据将对象字符串化。

             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);
        }
    });

要么,

       $.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);
        }
    });

-2

这些答案只是让我在无效参数和缺失参数之间来回跳动。

这对我有用,只需将字符串变量包装在引号中...

data: { RecordId: RecordId,
            UserId: UId,
            UserProfileId: UserProfileId,
            ItemType: '"' +  ItemType + '"',
            FileName: '"' +  XmlName + '"'
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.