Ajax处理中的“JSON基元无效”
我得到一个来自jQuery的ajax调用错误。
这是我的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" }
只是一个猜测什么variablesjson
包含之后
var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);?
如果它是一个有效的json对象,如{'foo':'foovalue', 'bar':'barvalue'}
那么jQuery可能不会将其作为json数据发送,而是将其序列化为foor=foovalue&bar=barvalue
"Invalid JSON primitive: foo"
尝试改为将数据设置为string
$.ajax({ ... data: "{'foo':'foovalue', 'bar':'barvalue'}", //note the additional quotation marks ... })
这样,jQuery应该单独保留数据,并将string按原样发送到服务器,以便ASP.NET能够parsingjson服务器端。
运用
data : JSON.stringify(obj)
在上面的情况下,我相信会有效果。
注意:你应该添加json2.js库所有的浏览器都不支持那个JSON对象(IE7-) json.js和json2.js之间的区别
如抖动所示, $.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" .... });
jQuery的Ajax将默认发送数据作为查询string参数的forms如:
RecordId=456&UserId=123
除非processData
选项设置为false,在这种情况下,它将作为对象发送到服务器。
-
contentType
选项是用于客户端发送数据格式的服务器。 -
dataType
选项是用于服务器,它告诉什么types的数据客户端期待从服务器回来。
不要指定contentType,以便服务器将它们parsing为查询string参数而不是json。
要么
使用contentType作为'application / json; charset = utf-8'并使用JSON.stringify(object),以便服务器能够从string反序列化json。
它正在这样的工作
data: JSON.stringify({'id':x}),
我猜@Jitter是对的,但他的解决scheme对我来说并不合适。
这是它的工作原理:
$.ajax({ ... data: "{ intFoo: " + intFoo + " }", ... });
我没有尝试,但我认为如果参数是一个string,它应该是这样的:
$.ajax({ ... data: "{ intFoo: " + intFoo + ", strBar: '" + strBar + "' }", ... });
如果手动格式化JSON,这里有一个非常方便的validation器: jsonlint.com
使用双引号而不是单引号:
无效:
{ 'project': 'a2ab6ef4-1a8c-40cd-b561-2112b6baffd6', 'franchise': '110bcca5-cc74-416a-9e2a-f90a8c5f63a0' }
有效:
{ "project": "a2ab6ef4-1a8c-40cd-b561-2112b6baffd6", "franchise": "18e899f6-dd71-41b7-8c45-5dc0919679ef" }
我面临同样的问题,我带来了很好的解决scheme如下:
尝试这个…
$.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"); } });
请注意这里stringtypes参数我已经使用(\)转义序列字符表示为string值。
在服务器上,序列化/反序列化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; }
这些答案只是让我在无效参数和缺失参数之间来回跳动。
这工作对我来说,只是用引号包装stringvariables…
data: { RecordId: RecordId, UserId: UId, UserProfileId: UserProfileId, ItemType: '"' + ItemType + '"', FileName: '"' + XmlName + '"' }