"ดั้งเดิม JSON ไม่ถูกต้อง" ในการประมวลผล Ajax


102

ฉันได้รับข้อผิดพลาดในการโทร ajax จาก jQuery

นี่คือฟังก์ชั่น 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"
}

สิ่งที่ฉันไม่เข้าใจคือ. จาวาสคริปต์เป็นเรื่องเกี่ยวกับ AddAlbumToMyProfile ในขณะที่ WebMethod เรียกว่า DeleteRecord คุณแน่ใจหรือว่าคุณแสดงโค้ดที่ถูกต้องให้เราเห็น?
กระวนกระวายใจ

มีโอกาสใดที่คุณสามารถจับภาพว่า POST มีลักษณะอย่างไร (โดยใช้ firebug หรือ whatnot) และเพิ่มลงในคำถาม? ฉันไม่แน่ใจว่าเป็นวิธีที่คุณเข้ารหัสข้อมูลก่อนส่งหรือไม่ แต่คุณสามารถลองทำให้เป็นอนุกรมโดยใช้สิ่งนี้ ( json.org/json2.js )
R0MANARMY

คำตอบ:


137

แค่เดาว่าตัวแปร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


6
ขอบคุณสำหรับคำชี้แจงเพิ่มอีกหนึ่งความคิดเห็นคุณสามารถทำได้เช่น JSON.stringify ({foo: 'foovalue', bar: 'barvalue'}) เพื่อชีวิตที่ง่ายขึ้น
เอเลน

ปลายทศวรรษที่ปาร์ตี้ แต่ยังคงมีความเกี่ยวข้องนั่นไม่ใช่ 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

1
โปรดทราบว่านี่เป็นวิธีแก้ปัญหาหากคุณต้องส่ง JSON ( ซึ่งคุณอาจใช้บริการเว็บ asp.net ) ในกรณีอื่นอาจทำได้ง่ายกว่าเพียงแค่ลบcontentTypeและปล่อยให้ jQuery ส่งผ่านข้อมูลที่เข้ารหัสแบบฟอร์ม
GSerg

19

ดังที่ระบุไว้โดย jitter $.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)งานได้สำหรับฉันหากคลาสจาวาสคริปต์ของคุณมีสไตล์var myObj = { title: "x", subclass = someVar, ... } เนื่องจากประเด็นเกี่ยวกับการเข้ารหัสข้อมูล
lko

19

มันใช้งานได้ประมาณนี้

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

3
คำตอบนี้ปรากฏในคิวการตรวจสอบคุณภาพต่ำซึ่งน่าจะเป็นเพราะคุณไม่ได้ให้คำอธิบายใด ๆ เกี่ยวกับโค้ด หากรหัสนี้ตอบคำถามให้ลองเพิ่มข้อความอธิบายรหัสในคำตอบของคุณ ด้วยวิธีนี้คุณมีแนวโน้มที่จะได้รับการโหวตเพิ่มมากขึ้นและช่วยให้ผู้ถามเรียนรู้สิ่งใหม่ ๆ
lmo

ฉันต้องการส่งผ่านพารามิเตอร์สองตัว: อาร์เรย์ของอ็อบเจ็กต์เชิงซ้อนและจำนวนเต็ม ฉันทำมัน: data: {items: JSON.stringify (myarray), myId: value}
ดารา

14

Jquery Ajax จะเริ่มต้นส่งข้อมูลเป็นพารามิเตอร์สตริงการสืบค้นเช่น:

RecordId=456&UserId=123

เว้นแต่processDataตัวเลือกจะถูกตั้งค่าเป็นเท็จซึ่งในกรณีนี้จะถูกส่งเป็นวัตถุไปยังเซิร์ฟเวอร์

  • contentType ตัวเลือกสำหรับเซิร์ฟเวอร์ที่ไคลเอ็นต์รูปแบบใดส่งข้อมูล

  • dataType ตัวเลือกสำหรับเซิร์ฟเวอร์ซึ่งจะบอกว่าไคลเอนต์ข้อมูลประเภทใดที่คาดหวังกลับมาจากเซิร์ฟเวอร์

อย่าระบุ contentType เพื่อให้เซิร์ฟเวอร์แยกวิเคราะห์เป็นพารามิเตอร์สตริงการสืบค้นไม่ใช่ json

หรือ

ใช้ contentType เป็น 'application / json; charset = utf-8 'และใช้ JSON.stringify (object) เพื่อให้เซิร์ฟเวอร์สามารถ deserialize json จากสตริงได้


5

ฉันเดาว่า @jitter คิดถูก แต่วิธีแก้ปัญหาของเขาไม่ได้ผลสำหรับฉัน

นี่คือสิ่งที่ได้ผล:

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

ฉันยังไม่ได้ลอง แต่ฉันคิดว่าถ้าพารามิเตอร์เป็นสตริงมันควรจะเป็นแบบนี้:

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

9
ถ้าฉันต้องเขียนโค้ดแบบนั้น (string 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

บนเซิร์ฟเวอร์เพื่อ Serialize / Deserialize 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"ทั้งบนหน้าหลักและหน้าป๊อปอัปด้วยรหัสควบคุมเดียวกัน การลบออกClientIDMode="Static"จากหน้าใดหน้าหนึ่งช่วยแก้ปัญหาได้


0

ในที่นี้ dataTpe คือ "json" ดังนั้น data / reqParam จะต้องอยู่ในรูปแบบของสตริงในขณะที่เรียก API ซึ่งมีจำนวนมากเท่าที่คุณต้องการ แต่สุดท้ายภายในข้อมูลของ $ .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 + '"'
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.