我试图发布一个JSON对象到asp.net webservice。
我的json是这样的:
var markers = { "markers": [
{ "position": "128.3657142857143", "markerPosition": "7" },
{ "position": "235.1944023323615", "markerPosition": "19" },
{ "position": "42.5978231292517", "markerPosition": "-3" }
]};
我使用json2.js来stringyfy我的JSON对象。
我使用jquery发布它到我的webservice。
$.ajax({
type: "POST",
url: "/webservices/PodcastService.asmx/CreateMarkers",
data: markers,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){alert(data);},
failure: function(errMsg) {
alert(errMsg);
}
});
我得到以下错误:
无效的JSON原语
我发现了一堆与此相关的帖子,这似乎是一个非常普遍的问题,但我没有尝试解决这个问题。
当firebug被发布到服务器时,它看起来是这样的:
标志物5B0 % 5D 5Bposition % 5D = 128 . 3657142857143&markers 5B0 % 5D % 5BmarkerPosition 5D = 7&markers 5B1 % 5D % 5Bposition 5D = 235 1944023323615&markers % 5B1 % 5D 5BmarkerPosition % 5D = 19&markers 5B2 % 5D 5Bposition % 5D = 42 . 5978231292517&markers 5B2 % 5D 5BmarkerPosition % 5D = - 3页
我的webservice函数被调用是:
[WebMethod]
public string CreateMarkers(string markerArray)
{
return "received markers";
}
你提到使用json2.js来stringify你的数据,但是post的数据似乎是URLEncoded JSON,你可能已经见过了,但是这篇关于无效JSON原语的文章涵盖了为什么JSON是URLEncoded。
我建议不要将原始的、手动序列化的JSON字符串传递到您的方法中。ASP。NET会自动对请求的POST数据进行JSON反序列化,所以如果你手动序列化并将JSON字符串发送给ASP。NET,你最终需要用JSON序列化你的JSON序列化字符串。
我的建议是:
var markers = [{ "position": "128.3657142857143", "markerPosition": "7" },
{ "position": "235.1944023323615", "markerPosition": "19" },
{ "position": "42.5978231292517", "markerPosition": "-3" }];
$.ajax({
type: "POST",
url: "/webservices/PodcastService.asmx/CreateMarkers",
// The key needs to match your method's input parameter (case-sensitive).
data: JSON.stringify({ Markers: markers }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){alert(data);},
error: function(errMsg) {
alert(errMsg);
}
});
避免无效JSON原语问题的关键是向jQuery传递数据参数的JSON字符串,而不是JavaScript对象,这样jQuery就不会尝试对数据进行URLEncode。
在服务器端,将方法的输入参数与传入的数据形状匹配:
public class Marker
{
public decimal position { get; set; }
public int markerPosition { get; set; }
}
[WebMethod]
public string CreateMarkers(List<Marker> Markers)
{
return "Received " + Markers.Count + " markers.";
}
如果你喜欢,你也可以接受一个数组,比如Marker[] Markers。ASMX ScriptServices使用的反序列化器(JavaScriptSerializer)非常灵活,可以将输入数据转换为您指定的服务器端类型。
我尝试了戴夫·沃德的解决方案。由于contentType被设置为“application/json”,数据部分没有从post请求的有效负载部分的浏览器发送。一旦我删除了这条线,一切都工作得很好。
var markers = [{ "position": "128.3657142857143", "markerPosition": "7" },
{ "position": "235.1944023323615", "markerPosition": "19" },
{ "position": "42.5978231292517", "markerPosition": "-3" }];
$.ajax({
type: "POST",
url: "/webservices/PodcastService.asmx/CreateMarkers",
// The key needs to match your method's input parameter (case-sensitive).
data: JSON.stringify({ Markers: markers }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){alert(data);},
failure: function(errMsg) {
alert(errMsg);
}
});
你提到使用json2.js来stringify你的数据,但是post的数据似乎是URLEncoded JSON,你可能已经见过了,但是这篇关于无效JSON原语的文章涵盖了为什么JSON是URLEncoded。
我建议不要将原始的、手动序列化的JSON字符串传递到您的方法中。ASP。NET会自动对请求的POST数据进行JSON反序列化,所以如果你手动序列化并将JSON字符串发送给ASP。NET,你最终需要用JSON序列化你的JSON序列化字符串。
我的建议是:
var markers = [{ "position": "128.3657142857143", "markerPosition": "7" },
{ "position": "235.1944023323615", "markerPosition": "19" },
{ "position": "42.5978231292517", "markerPosition": "-3" }];
$.ajax({
type: "POST",
url: "/webservices/PodcastService.asmx/CreateMarkers",
// The key needs to match your method's input parameter (case-sensitive).
data: JSON.stringify({ Markers: markers }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){alert(data);},
error: function(errMsg) {
alert(errMsg);
}
});
避免无效JSON原语问题的关键是向jQuery传递数据参数的JSON字符串,而不是JavaScript对象,这样jQuery就不会尝试对数据进行URLEncode。
在服务器端,将方法的输入参数与传入的数据形状匹配:
public class Marker
{
public decimal position { get; set; }
public int markerPosition { get; set; }
}
[WebMethod]
public string CreateMarkers(List<Marker> Markers)
{
return "Received " + Markers.Count + " markers.";
}
如果你喜欢,你也可以接受一个数组,比如Marker[] Markers。ASMX ScriptServices使用的反序列化器(JavaScriptSerializer)非常灵活,可以将输入数据转换为您指定的服务器端类型。