«Недопустимый примитив JSON» в обработке Ajax - PullRequest
88 голосов
/ 15 марта 2010

Я получаю сообщение об ошибке при вызове 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"
}

Ответы [ 10 ]

121 голосов
/ 15 марта 2010

Просто угадайте, что содержит переменная 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.

97 голосов
/ 26 ноября 2011

Использование

data : JSON.stringify(obj)

в вышеприведенной ситуации работало бы, я полагаю.

Примечание. Необходимо добавить библиотеку json2.js, все браузеры не поддерживают этот объект JSON (IE7-). Разница между json.js и json2.js

18 голосов
/ 22 марта 2010

Как отмечает 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"
    ....
});
15 голосов
/ 07 сентября 2016

это работает как то так

data: JSON.stringify({'id':x}),
11 голосов
/ 06 июля 2014

Jquery Ajax по умолчанию отправляет данные в виде параметров строки запроса, например:

RecordId=456&UserId=123

, если для параметра processData не установлено значение false, в этом случае оно будет отправлено на сервер как объект.

  • contentType - для сервера, в каком формате клиент отправил данные.

  • dataType опция для сервера, который сообщает, что тип данных клиент ожидает возврата с сервера.

Не указывайте contentType, чтобы сервер анализировал их как запрос Строковые параметры не такие как json.

OR

Использовать contentType в качестве 'application / json; charset = utf-8 'и использовать JSON.stringify (object), чтобы сервер мог десериализовать json из строки.

5 голосов
/ 15 июля 2011

Полагаю, @jitter был прав, но его решение не сработало для меня.

Вот как это работает:

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

Я не пробовал, но я думаю, что если параметром является строка, она должна выглядеть следующим образом:

$.ajax({
    ...
    data: "{ intFoo: " + intFoo + ", strBar: '" + strBar + "' }",
    ...
});
2 голосов
/ 23 сентября 2015

Я столкнулся с той же проблемой, что я нашел с хорошим решением, как показано ниже:

Попробуйте это ...

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

Обратите внимание, здесь для параметра строкового типа я использовал (\ ') символ escape-последовательности для обозначения его как строкового значения.

1 голос
/ 08 ноября 2012

Если вручную отформатировать JSON, здесь есть очень удобный валидатор: jsonlint.com

Используйте двойные кавычки вместо одинарных:

Invalid:

{
    '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 голосов
/ 14 октября 2013

эти ответы только что заставили меня подпрыгивать между неверным параметром и отсутствующим параметром.

это сработало для меня, просто заключите строковые переменные в кавычки ...

data: { RecordId: RecordId,
            UserId: UId,
            UserProfileId: UserProfileId,
            ItemType: '"' +  ItemType + '"',
            FileName: '"' +  XmlName + '"'
    }
0 голосов
/ 14 декабря 2011

На сервере для сериализации / десериализации 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;
}
...