“Primitiva JSON inválida” en el procesamiento de Ajax

Recibo un error en una llamada ajax de jQuery.

Aquí está mi función 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"); } }); } 

y este es mi 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"; } 

¿Alguien puede decirme qué hay de malo en mi código?

Estoy recibiendo este error:

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

    Solo adivina qué contiene la variable json después de

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

    Si es un objeto json válido como {'foo':'foovalue', 'bar':'barvalue'} entonces jQuery podría no enviarlo como datos json sino serializarlo en foor=foovalue&bar=barvalue así se obtiene el error "Invalid JSON primitive: foo"

    En su lugar, intente configurar los datos como una cadena

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

    De esta forma jQuery debería dejar los datos solos y enviar la cadena como está al servidor, lo que debería permitir a ASP.NET analizar el lado del servidor json.

    Utilizando

     data : JSON.stringify(obj) 

    en la situación anterior hubiera funcionado, creo.

    Nota: Debe agregar la biblioteca json2.js. Todos los navegadores no admiten ese objeto JSON (IE7-) Diferencia entre json.js y json2.js

    Como lo señala jitter, la función $.ajax serializa cualquier objeto / matriz utilizado como parámetro de data en un formato codificado en url. Por extraño que parezca, el parámetro dataType solo se aplica a la respuesta del servidor, y no a los datos de la solicitud.

    Después de encontrar el mismo problema, descargué y usé el complemento jquery-json para codificar correctamente los datos de solicitud en ScriptService. Luego, usó la función $.toJSON para codificar los argumentos deseados para enviar al servidor:

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

    Jquery Ajax enviará los datos por defecto como parámetros de cadena de consulta como:

     RecordId=456&UserId=123 

    a menos que la opción processData se establezca en falso, en cuyo caso se enviará como objeto al servidor.

    • contentType opción contentType es para el servidor en el que el cliente de formato ha enviado los datos.

    • dataType opción dataType es para el servidor que indica qué tipo de cliente de datos espera del servidor.

    No especifique contentType para que el servidor los analice como parámetros String de consulta, no como json.

    O

    Use contentType como ‘application / json; charset = utf-8 ‘y usa JSON.stringify (object) para que el servidor pueda deserializar json de la cadena.

    está funcionando algo como esto

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

    Supongo que @jitter tenía razón en su suposición, pero su solución no funcionó para mí.

    Esto es lo que funcionó:

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

    No lo he intentado, pero creo que si el parámetro es una cadena, debería ser así:

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

    Si formatea manualmente JSON, aquí hay un validador muy útil: jsonlint.com

    Use comillas dobles en lugar de comillas simples:

    Inválido:

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

    Válido:

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

    Estaba enfrentando el mismo problema, lo que vine con una buena solución es la siguiente:

    Prueba esto…

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

    Observe aquí para el parámetro de tipo de cadena que he usado (\ ‘) el carácter de secuencia de escape para denotarlo como valor de cadena.

    En el servidor, para serializar / deserializar json en objetos personalizados:

     public static string Serialize(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(string json) { T obj = Activator.CreateInstance(); MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)); DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType()); obj = (T)serializer.ReadObject(ms); ms.Close(); return obj; } 

    estas respuestas me hicieron rebotar entre parámetros inválidos y parámetros faltantes.

    esto funcionó para mí, simplemente ajuste las variables de cadena entre comillas …

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