“Nguyên thủy JSON không hợp lệ” trong xử lý Ajax


101

Tôi gặp lỗi trong cuộc gọi ajax từ jQuery.

Đây là hàm jQuery của tôi:

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

và đây là của tôi 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";
}

Ai có thể vui lòng cho tôi biết mã của tôi có gì sai không?

Tôi nhận được lỗi này:

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

Những gì tôi không hiểu là. Javascript là về AddAlbumToMyProfile trong khi WebMethod được gọi là DeleteRecord. Bạn có chắc là bạn chỉ cho chúng tôi đúng đoạn mã không?
jitter

Bất kỳ cơ hội nào bạn cũng có thể nắm bắt POST trông như thế nào (sử dụng firebug hoặc whatnot) và thêm nó vào câu hỏi? Tôi không chắc đó có phải là cách bạn mã hóa dữ liệu trước khi gửi hay không, nhưng bạn cũng có thể thử tuần tự hóa nó bằng cách sử dụng cách này ( json.org/json2.js ).
R0MANARMY

Câu trả lời:


135

Chỉ cần đoán xem biến jsonchứa gì sau

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

Nếu đó là một đối tượng json hợp lệ như vậy {'foo':'foovalue', 'bar':'barvalue'}thì jQuery có thể không gửi nó dưới dạng dữ liệu json mà thay vào đó là tuần tự hóa nó để foor=foovalue&bar=barvaluebạn gặp lỗi"Invalid JSON primitive: foo"

Thay vào đó, hãy thử đặt dữ liệu dưới dạng chuỗi

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

Bằng cách này, jQuery nên để riêng dữ liệu và gửi chuỗi như vậy đến máy chủ, điều này sẽ cho phép ASP.NET phân tích cú pháp phía máy chủ json.


5
cảm ơn bạn đã giải thích rõ, hãy thêm một nhận xét nữa, bạn luôn có thể làm như JSON.stringify ({foo: 'foovalue', bar: 'barvalue'}) để có cuộc sống dễ dàng hơn
Elaine

Đến muộn một thập kỷ, nhưng vẫn có liên quan: đó không phải là JSON hợp lệ. Các chuỗi (bao gồm tên thuộc tính) trong JSON phải sử dụng dấu ngoặc kép , vì vậy nó sẽ phải như vậy {"foo": "foovalue", "bar": "barvalue"}. Sử dụng dấu ngoặc kép là một lỗi cú pháp.
Mike 'Pomax' Kamermans

108

Sử dụng

data : JSON.stringify(obj)

trong tình huống trên sẽ có hiệu quả, tôi tin rằng.

Lưu ý: Bạn nên thêm thư viện json2.js tất cả các trình duyệt không hỗ trợ đối tượng JSON đó (IE7-) Sự khác biệt giữa json.js và json2.js


3
Cảm ơn! Khi sử dụng các lớp JS đơn giản, điều này hoạt động. Tôi đã thay đổi data: { JSON.stringify(obj) }thành data: JSON.stringify(obj)(Lớp javascript / JSON của tôi để tuần tự hóa là theo phong cách var myObj = { title: "x", subclass = someVar, ... } )
lko

1
Lưu ý rằng đây là giải pháp miễn là bạn thực sự cần gửi JSON ( mà bạn có thể có với các dịch vụ web asp.net ). Trong các trường hợp khác, có thể dễ dàng hơn chỉ cần xóacontentType và để jQuery chuyển dữ liệu được mã hóa biểu mẫu.
GSerg

19

Như đã lưu ý bởi jitter, $.ajaxhàm tuần tự hóa bất kỳ đối tượng / mảng nào được sử dụng làm datatham số thành định dạng được mã hóa url. Thật kỳ lạ, dataTypetham số chỉ áp dụng cho phản hồi từ máy chủ - và không áp dụng cho bất kỳ dữ liệu nào trong yêu cầu.

Sau khi gặp sự cố tương tự, tôi đã tải xuống và sử dụng plugin jquery-json để mã hóa chính xác dữ liệu yêu cầu sang ScriptService. Sau đó, sử dụng $.toJSONhàm để mã hóa các đối số mong muốn để gửi đến máy chủ:

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

2
cảm ơn vì đã chỉ ra rằng datatham số bị bỏ qua bởi cuộc gọi.
Noel Abrahams

3
Điều này hoạt động, nhưng thay đổi data: { JSON.stringify(obj) }thành phù data: JSON.stringify(obj)hợp với tôi nếu lớp javascript của bạn có phong cách tốt var myObj = { title: "x", subclass = someVar, ... } nhờ vào điểm về mã hóa dữ liệu.
lko

19

nó đang hoạt động như thế này

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

3
Câu trả lời này xuất hiện trong hàng đợi đánh giá chất lượng thấp, có thể là do bạn không cung cấp bất kỳ giải thích nào về mã. Nếu mã này trả lời câu hỏi, hãy xem xét thêm một số văn bản giải thích mã trong câu trả lời của bạn. Bằng cách này, bạn có nhiều khả năng nhận được nhiều sự ủng hộ hơn - và giúp người hỏi học được điều gì đó mới.
lmo

Tôi muốn truyền hai tham số: một mảng đối tượng phức tạp và một số nguyên. Tôi làm điều đó: data: {items: JSON.stringify (myarray), myId: value}.
A.Dara

cảm ơn vì đã đăng câu trả lời. điều này đã làm việc cho tôi.
ZMAX

13

Jquery Ajax mặc định sẽ gửi dữ liệu ở dạng tham số chuỗi truy vấn như:

RecordId=456&UserId=123

trừ khi processDatatùy chọn được đặt thành false, trong trường hợp đó, nó sẽ được gửi dưới dạng đối tượng đến máy chủ.

  • contentType tùy chọn dành cho máy chủ mà máy khách định dạng đã gửi dữ liệu.

  • dataType tùy chọn dành cho máy chủ cho biết loại máy khách dữ liệu nào đang mong đợi phản hồi từ máy chủ.

Không chỉ định contentType để máy chủ sẽ phân tích cú pháp chúng dưới dạng tham số chuỗi truy vấn không phải là json.

HOẶC LÀ

Sử dụng contentType là 'application / json; charset = utf-8 'và sử dụng JSON.stringify (object) để máy chủ có thể giải mã json khỏi chuỗi.


5

Tôi đoán @jitter đã đúng trong suy đoán của anh ấy, nhưng giải pháp của anh ấy không phù hợp với tôi.

Đây là những gì nó đã hoạt động:

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

Tôi chưa thử nhưng tôi nghĩ nếu tham số là một chuỗi thì nó sẽ như thế này:

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

9
Nếu tôi phải viết mã như thế (chuỗi concat) để tạo các đối tượng JSON, tôi sẽ tự giết mình (nói theo nghĩa bóng). Có phải là một cách tốt hơn.
PandaWood

3

Tôi đã gặp phải vấn đề tương tự, những gì tôi đã đưa ra với giải pháp tốt là như sau:

Thử cái này...

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

Xin lưu ý ở đây đối với tham số kiểu chuỗi mà tôi đã sử dụng (\ ') ký tự chuỗi thoát để biểu thị nó là giá trị chuỗi.


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

1

Nếu định dạng thủ công JSON, có một trình xác thực rất hữu ích ở đây: jsonlint.com

Sử dụng dấu ngoặc kép thay vì dấu nháy đơn:

Không hợp lệ:

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

Có hiệu lực:

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

0

Trên Server, để Serialize / Deserialize json thành các đối tượng tùy chỉnh:

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

Tôi gặp vấn đề tương tự. Tôi đang gọi trang mẹ "Lưu" từ Cửa sổ bật lên Đóng. Nhận thấy rằng tôi đang sử dụng ClientIDMode="Static"trên cả trang mẹ và trang bật lên với cùng một id điều khiển. Xóa ClientIDMode="Static"khỏi một trong các trang đã giải quyết được vấn đề.


0

Ở đây dataTpe là "json" vì vậy, data / reqParam phải ở dạng chuỗi trong khi gọi API, nhiều đối tượng tùy thích nhưng cuối cùng bên trong dữ liệu của $ .ajax sẽ xâu chuỗi đối tượng.

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

HOẶC LÀ,

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

những câu trả lời này chỉ khiến tôi bị trả về giữa tham số không hợp lệ và tham số bị thiếu.

điều này làm việc cho tôi, chỉ cần đặt các biến chuỗi trong dấu ngoặc kép ...

data: { RecordId: RecordId,
            UserId: UId,
            UserProfileId: UserProfileId,
            ItemType: '"' +  ItemType + '"',
            FileName: '"' +  XmlName + '"'
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.