“Primitivo JSON inválido” no processamento Ajax
Pergunta
Estou recebendo um erro em uma chamada ajax do jQuery.
Aqui está minha função 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");
}
});
}
e este é o meu 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";
}
Alguém pode me dizer o que há de errado no meu código?
Estou recebendo este erro:
{
"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"
}
Solução
Apenas um palpite o que faz a variável json
conter depois
var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);?
Se for um objeto JSON válido como {'foo':'foovalue', 'bar':'barvalue'}
Então, o jQuery pode não enviá -lo como dados JSON, mas em vez de serializar -os para foor=foovalue&bar=barvalue
Assim você recebe o erro "Invalid JSON primitive: foo"
Tente definir os dados como string
$.ajax({
...
data: "{'foo':'foovalue', 'bar':'barvalue'}", //note the additional quotation marks
...
})
Dessa forma, o jQuery deve deixar os dados em paz e enviar a string como é para o servidor que deve permitir que o ASP.NET analise o lado do servidor JSON.
Outras dicas
Usando
data : JSON.stringify(obj)
Na situação acima teria funcionado, acredito.
Nota: você deve adicionar biblioteca JSON2.JS Todos os navegadores não suportam esse objeto JSON (ie7-)Diferença entre json.js e json2.js
Como observado pelo jitter, o $.ajax
Função serializa qualquer objeto/matriz usado como o data
parâmetro em um formato codificado por URL. Curiosamente, o dataType
O parâmetro se aplica apenas à resposta do servidor - e não a nenhum dado na solicitação.
Depois de encontrar o mesmo problema, baixei e usei o plugin jQuery-json Para codificar corretamente os dados de solicitação ao ScriptService. Então, usou o $.toJSON
função para codificar os argumentos desejados para enviar ao servidor:
$.ajax({
type: "POST",
url: "EditUserProfile.aspx/DeleteRecord",
data: $.toJSON(obj),
contentType: "application/json; charset=utf-8",
dataType: "json"
....
});
está funcionando algo assim
data: JSON.stringify({'id':x}),
JQuery Ajax irá enviar os dados como o formulário de parâmetros de sequência de consulta como:
RecordId=456&UserId=123
A menos que o processData
A opção está definida como falsa; nesse caso, será enviado como objeto para o servidor.
contentType
A opção é para o servidor em que o cliente de formato enviou os dados.dataType
A opção é para o servidor que informa que o tipo de cliente de dados está esperando de volta do servidor.
Não especifique o contentType para que o servidor os analise como parâmetros de sequência de consulta não como JSON.
OU
Use contentType como 'Application/JSON; charset = utf-8 'e use json.stringify (objeto) para que o servidor pudesse desserializar o json da string.
Eu acho que @jitter estava certo em seu palpite, mas sua solução não funcionou para mim.
Aqui está o que funcionou:
$.ajax({
...
data: "{ intFoo: " + intFoo + " }",
...
});
Eu não tentei, mas acho que se o parametter for uma string, deve ser assim:
$.ajax({
...
data: "{ intFoo: " + intFoo + ", strBar: '" + strBar + "' }",
...
});
Eu estava enfrentando o mesmo problema, o que vim com boa solução é como abaixo:
Experimente isso ...
$.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 aqui o parâmetro de tipo de string que usei ( ') Personagem de sequência de escape para denotar -o como valor da string.
Se formatar manualmente o JSON, existe um validador muito útil aqui: jsonlint.com
Use citações duplas em vez de citações únicas:
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"
}
No servidor, para serializar/desserialize o JSON para objetos personalizados:
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;
}
Eu tive o mesmo problema. Eu estava chamando a página dos pais de "salvar" da janela pop -up de fechamento. Descobri que eu estava usando ClientIDMode="Static"
na página pai e pop -up com o mesmo ID de controle. Removendo ClientIDMode="Static"
de uma das páginas resolveu o problema.
essas respostas me fizeram oscilar entre parâmetros inválidos e parâmetros ausentes.
isso funcionou para mim, apenas coloque as variáveis de string entre aspas ...
data: { RecordId: RecordId,
UserId: UId,
UserProfileId: UserProfileId,
ItemType: '"' + ItemType + '"',
FileName: '"' + XmlName + '"'
}