"Primitif JSON tidak valid" dalam pemrosesan Ajax


101

Saya mendapatkan kesalahan dalam panggilan ajax dari jQuery.

Inilah fungsi jQuery saya:

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

dan ini milikku 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";
}

Adakah yang bisa memberi tahu saya apa yang salah dalam kode saya?

Saya mendapatkan kesalahan ini:

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

Yang tidak saya mengerti adalah. Javascript adalah tentang AddAlbumToMyProfile sedangkan WebMethod disebut DeleteRecord. Anda yakin menunjukkan potongan kode yang benar?
jitter

Adakah kesempatan Anda juga dapat menangkap seperti apa POST itu (menggunakan firebug atau yang lainnya) dan menambahkannya ke pertanyaan? Saya tidak yakin apakah itu cara Anda menyandikan data sebelum mengirimnya, tetapi Anda juga dapat mencoba membuat serial menggunakan ini ( json.org/json2.js ).
R0MANARMY

Jawaban:


136

Coba tebak isi variabel jsonsetelahnya

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

Jika itu adalah objek json yang valid seperti {'foo':'foovalue', 'bar':'barvalue'}maka jQuery mungkin tidak mengirimnya sebagai data json tetapi sebagai gantinya membuat serial foor=foovalue&bar=barvaluesehingga Anda mendapatkan kesalahan"Invalid JSON primitive: foo"

Coba atur data sebagai string

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

Dengan cara ini jQuery harus membiarkan datanya sendiri dan mengirim string apa adanya ke server yang memungkinkan ASP.NET untuk mengurai sisi server json.


5
terima kasih atas klarifikasinya, tambahkan satu komentar lagi, Anda selalu dapat melakukan seperti JSON.stringify ({foo: 'foovalue', bar: 'barvalue'}) untuk hidup yang lebih mudah
Elaine

Terlambat satu dekade ke pesta, tetapi masih relevan: itu bukan JSON yang valid. String (termasuk nama properti) di JSON harus menggunakan tanda kutip ganda , jadi harus seperti itu {"foo": "foovalue", "bar": "barvalue"}. Menggunakan tanda kutip tunggal adalah kesalahan sintaksis.
Mike 'Pomax' Kamermans

108

Menggunakan

data : JSON.stringify(obj)

dalam situasi di atas akan berhasil saya percaya.

Catatan: Anda harus menambahkan pustaka json2.js semua browser tidak mendukung objek JSON (IE7-) Perbedaan antara json.js dan json2.js


3
Terima kasih! Saat menggunakan kelas JS sederhana, ini berfungsi. Saya berubah data: { JSON.stringify(obj) }menjadi data: JSON.stringify(obj)(kelas javascript / JSON saya menjadi serial adalah gaya var myObj = { title: "x", subclass = someVar, ... } )
lko

1
Perhatikan bahwa ini adalah solusi asalkan Anda benar-benar perlu mengirim JSON ( yang mungkin Anda lakukan dengan layanan web asp.net ). Dalam kasus lain, mungkin lebih mudah untuk menghapuscontentType dan membiarkan jQuery meneruskan data yang dikodekan formulir.
GSerg

19

Seperti dicatat oleh jitter, $.ajaxfungsi tersebut membuat serial objek / larik apa pun yang digunakan sebagai dataparameter ke dalam format yang dikodekan url. Anehnya, dataTypeparameter hanya berlaku untuk respons dari server - dan tidak untuk data apa pun dalam permintaan.

Setelah mengalami masalah yang sama, saya mengunduh dan menggunakan plugin jquery-json untuk menyandikan data permintaan dengan benar ke ScriptService. Kemudian, gunakan $.toJSONfungsi untuk mengenkode argumen yang diinginkan untuk dikirim ke server:

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

2
terima kasih telah menunjukkan bahwa dataparameter diabaikan oleh panggilan tersebut.
Noel Abrahams

3
Ini berfungsi, tetapi mengubah data: { JSON.stringify(obj) }menjadi data: JSON.stringify(obj)berhasil untuk saya jika kelas javascript Anda bergaya var myObj = { title: "x", subclass = someVar, ... } berkat poin tentang pengkodean data.
lko

19

itu bekerja seperti ini

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

3
Jawaban ini muncul dalam antrean ulasan berkualitas rendah, mungkin karena Anda tidak memberikan penjelasan tentang kode tersebut. Jika kode ini menjawab pertanyaan, pertimbangkan untuk menambahkan beberapa teks yang menjelaskan kode dalam jawaban Anda. Dengan cara ini, Anda jauh lebih mungkin mendapatkan lebih banyak suara positif - dan membantu penanya mempelajari sesuatu yang baru.
lmo

Saya ingin melewatkan dua parameter: array objek kompleks dan integer. Saya melakukannya: data: {items: JSON.stringify (myarray), myId: value}.
A.Dara

13

Jquery Ajax secara default akan mengirimkan data sebagai parameter string kueri berbentuk seperti:

RecordId=456&UserId=123

kecuali jika processDataopsi disetel ke false, dalam hal ini akan dikirim sebagai objek ke server.

  • contentType opsi untuk server yang format klien telah mengirim data.

  • dataType Opsi adalah untuk server yang memberi tahu bahwa jenis data apa yang diharapkan klien dari server.

Jangan tentukan contentType sehingga server akan menguraikannya sebagai parameter String kueri bukan sebagai json.

ATAU

Gunakan contentType sebagai 'application / json; charset = utf-8 'dan gunakan JSON.stringify (object) sehingga server akan dapat memisahkan json dari string.


5

Sepertinya @jitter benar dalam tebakannya, tetapi solusinya tidak berhasil untuk saya.

Inilah yang berhasil:

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

Saya belum mencoba tetapi saya pikir jika parametter adalah string, seharusnya seperti ini:

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

9
Jika saya harus menulis kode seperti itu (string concat) untuk membuat objek JSON, saya akan bunuh diri (secara kiasan). Pasti ada cara yang lebih baik.
PandaWood

3

Saya menghadapi masalah yang sama, apa yang saya dapatkan dengan solusi yang baik adalah sebagai berikut:

Coba ini...

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

Harap dicatat di sini untuk parameter tipe string saya telah menggunakan (\ ') karakter urutan melarikan diri untuk menunjukkannya sebagai nilai string.


data: "{Notes: \" "+ $ ('# txtNotes'). val () +" \ "}
bestinamir

1

Jika memformat JSON secara manual, ada validator yang sangat berguna di sini: jsonlint.com

Gunakan tanda kutip ganda, bukan tanda kutip tunggal:

Tidak valid:

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

Sah:

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

0

Di Server, untuk membuat serial / deserialisasi json ke objek kustom:

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

Saya memiliki masalah yang sama. Saya menelepon halaman induk "Simpan" dari jendela Popup Tutup. Menemukan bahwa saya menggunakan ClientIDMode="Static"pada halaman induk dan popup dengan ID kontrol yang sama. Menghapus ClientIDMode="Static"dari salah satu halaman menyelesaikan masalah.


0

Di sini dataTpe adalah "json" jadi, data / reqParam harus dalam bentuk string saat memanggil API, sebanyak objek yang Anda inginkan tetapi akhirnya di dalam data $ .ajax merangkai objek tersebut.

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

ATAU,

       $.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

jawaban ini hanya membuat saya bolak-balik antara parameter yang tidak valid dan parameter yang hilang.

ini berhasil untuk saya, cukup bungkus variabel string dalam tanda kutip ...

data: { RecordId: RecordId,
            UserId: UId,
            UserProfileId: UserProfileId,
            ItemType: '"' +  ItemType + '"',
            FileName: '"' +  XmlName + '"'
    }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.