"Primitive JSON invalide" dans le traitement Ajax
je reçois une erreur dans un appel ajax de jQuery.
voici ma fonction 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");
}
});
}
et voici mon 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";
}
est-ce que quelqu'un peut me dire ce qui ne va pas dans mon code?
je reçois cette erreur:
{
"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 réponses
Juste une supposition que la variable json
contenir après
var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);?
si c'est un objet JSON valide comme {'foo':'foovalue', 'bar':'barvalue'}
alors jQuery pourrait ne pas l'envoyer comme données json mais au lieu de sérialiser à foor=foovalue&bar=barvalue
ainsi vous obtenez l'erreur "Invalid JSON primitive: foo"
essayer à la place de définir les données comme chaîne de caractères
$.ajax({
...
data: "{'foo':'foovalue', 'bar':'barvalue'}", //note the additional quotation marks
...
})
de cette façon jQuery devrait laisser les données seules et envoyer la chaîne telle quelle au serveur qui devrait autoriser ASP.NET pour analyser le côté serveur json.
utilisant
data : JSON.stringify(obj)
dans la situation ci-dessus aurait fonctionné je crois.
Note: vous devez ajouter json2.tous les navigateurs ne prennent pas en charge cet objet JSON (IE7-) Différence entre json.js et json2.js
comme l'a noté jitter, la fonction $.ajax
sérialise tout objet/tableau utilisé comme paramètre data
dans un format encodé url. Curieusement, le paramètre dataType
ne s'applique qu'à la réponse du serveur - et non à aucune donnée de la requête.
après avoir rencontré le même problème, j'ai téléchargé et utilisé le plugin jquery-json pour encoder correctement les données de la requête vers le service Scripts. Puis, utilisé le $.toJSON
fonction pour encoder les arguments désirés à envoyer au serveur:
$.ajax({
type: "POST",
url: "EditUserProfile.aspx/DeleteRecord",
data: $.toJSON(obj),
contentType: "application/json; charset=utf-8",
dataType: "json"
....
});
ça marche quelque chose comme ça
data: JSON.stringify({'id':x}),
Jquery Ajax enverra par défaut les données sous la forme de paramètres de chaîne de requête comme:
RecordId=456&UserId=123
sauf si l'option processData
est définie à false, auquel cas elle sera envoyée comme objet au serveur.
-
contentType
l'option est pour le serveur dans lequel le client a envoyé les données. -
dataType
option est pour le serveur qui indique que quel type de données le client attend un retour du serveur.
ne spécifiez pas contentType pour que le serveur Les analyse comme requête Les paramètres de la chaîne ne sont pas json.
ou
utiliser contentType comme 'application / json; charset=utf-8' et utiliser JSON.stringify (object) pour que le serveur puisse désérialiser json à partir de string.
je suppose que @jitter avait raison à son avis, mais sa solution n'a pas fonctionné pour moi.
voici ce qui a fonctionné:
$.ajax({
...
data: "{ intFoo: " + intFoo + " }",
...
});
Je n'ai pas essayé mais je pense que si le paramètre est une chaîne, il devrait être comme ceci:
$.ajax({
...
data: "{ intFoo: " + intFoo + ", strBar: '" + strBar + "' }",
...
});
je faisais face à la même question, ce que je suis venu avec la bonne solution est comme ci-dessous:
essayez ceci...
$.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");
}
});
veuillez noter ici pour le paramètre de type de chaîne de caractères que j'ai utilisé (\') le caractère de séquence d'échappement pour le dénoter comme valeur de chaîne de caractères.
si vous formatez manuellement JSON, il y a un validateur très pratique ici: jsonlint.com
utilisez des guillemets au lieu de guillemets simples:
invalide:
{
'project': 'a2ab6ef4-1a8c-40cd-b561-2112b6baffd6',
'franchise': '110bcca5-cc74-416a-9e2a-f90a8c5f63a0'
}
Valide:
{
"project": "a2ab6ef4-1a8c-40cd-b561-2112b6baffd6",
"franchise": "18e899f6-dd71-41b7-8c45-5dc0919679ef"
}
sur le serveur, pour sérialiser / Deserialiser json vers des objets personnalisés:
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;
}
ces réponses m'ont fait rebondir entre paramètre invalide et Paramètre manquant.
cela a fonctionné pour moi , juste envelopper les variables de chaîne dans des guillemets...
data: { RecordId: RecordId,
UserId: UId,
UserProfileId: UserProfileId,
ItemType: '"' + ItemType + '"',
FileName: '"' + XmlName + '"'
}