"Недопустимый примитив JSON" в обработке Ajax

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

Ответ 1

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

Ответ 2

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

data : JSON.stringify(obj)

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

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

Ответ 3

Как отмечено дрожанием, функция $.ajax выполняет сериализацию любого объекта/массива, используемого как параметр data, в формате с кодировкой url. Как ни странно, параметр dataType применяется только к ответу с сервера, а не к каким-либо данным в запросе.

После того, как я столкнулся с той же проблемой, я загрузил и использовал jquery-json plugin, чтобы правильно кодировать данные запроса в ScriptService. Затем использовалась функция $.toJSON для кодирования требуемых аргументов для отправки на сервер:

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

Ответ 4

работает что-то вроде этого

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

Ответ 5

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

RecordId=456&UserId=123

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

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

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

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

ИЛИ

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

Ответ 6

Я думаю, что @jitter был прав в своих предположениях, но его решение не сработало для меня.

Вот что он сделал:

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

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

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

Ответ 7

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

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

$.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-последовательности для обозначения его как строкового значения.

Ответ 8

Если вручную форматировать 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"
}

Ответ 9

На сервере, чтобы Сериализовать /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;
}

Ответ 10

Я была такая же проблема. Я звонил родительской странице "Сохранить" из всплывающего окна "Закрыть". Обнаружил, что я использовал ClientIDMode="Static" как на родительской, так и на всплывающей странице с одинаковым контрольным идентификатором. Удаление ClientIDMode="Static" с одной из страниц решило проблему.

Ответ 11

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

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

data: { RecordId: RecordId,
            UserId: UId,
            UserProfileId: UserProfileId,
            ItemType: '"' +  ItemType + '"',
            FileName: '"' +  XmlName + '"'
    }