See 丹尼的帖子 http://www.dennydotnet.com/post/Passing-a-JSON-object-to-a-WCF-service-with-jQuery.aspx首先,尽管我不同意他使用 GET 以及在查询字符串中传递 JSON 来获取复杂的参数。这看起来确实是错误的。
您使用的参数data
是您的分辨率类型的 json 表示形式。例如,假设类型和操作在服务器端定义如下:
[DataContract( Namespace = "urn:brandon.michael.hunter/ws/2010/01",
Name = "Resolution" )]
public class Resolution
{
[DataMember( IsRequired = true, Name = "Name" )]
public string Name { get; set; }
[DataMember( IsRequired = true, Name = "Rank" )]
public int Rank { get; set; }
[DataMember( IsRequired = true, Name = "SerialNumber" )]
public int SerialNumber { get; set; }
[DataMember( IsRequired = false, Name = "Id" )]
public int Id { get; set; }
}
[OperationContract]
[WebInvoke(Method = "PUT",
RequestFormat=WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "new")]
public Resolution CreateNewResolution(Resolution r)
{
// your logic here
r.Id = System.Guid.NewGuid();
return r;
}
然后,在 Javascript 中,您使用的代码可能如下所示:
var resolution = {r: { Name : "Fred", Rank : 2, SerialNumber : 17268 }};
// convert object to JSON string (See http://jollytoad.googlepages.com/json.js)
var objectAsJson = $.toJSON(resolution);
// result is a string: '{"Name":"Fred","Rank":"2","SerialNumber":"17268"}'
$.ajax({
type : "PUT", // must match Method in WebInvoke
contentType : "application/json",
url : "Service.svc/new", // must match UriTemplate in WebInvoke
data : objectAsJson,
dataFilter : function (data, type) {
// convert from "\/Date(nnnn)\/" to "new Date(nnnn)"
return data.replace(/"\\\/(Date\([0-9-]+\))\\\/"/gi, 'new $1');
},
processData : false, // do not convert outbound data to string (already done)
success : function(msg){ ... },
error : function(xhr, textStatus, errorThrown){ ... }
});
Notes:
- 您需要将变量 (r) 的名称作为正在传递的 JSON 中的第一个对象,至少对于 WCF 4 是这样。当我使用前面的示例时,直到我输入变量的名称后,它才起作用。变量在开头。
- 要以 JSON 传递复杂对象,请使用 PUT 或 POST 作为请求的类型(HTTP 方法)
- 您需要将复杂对象转换为 JSON 字符串。有一个不错的小 jquery 插件来做到这一点 http://jollytoad.googlepages.com/json.js. Denny http://www.dennydotnet.com/post/Passing-a-JSON-object-to-a-WCF-service-with-jQuery.aspx提供了他自己的实现。
- 我发现如果我使用
processData=true
,那么发送到服务的结果字符串将采用查询字符串格式,而不是 JSON 格式。不是我想要传递复杂对象的。所以我把它设置为 false。对于执行 WebGet 的更简单的非 JSON 请求,使用 true 就可以了,并且所有参数都在查询字符串中。
- dataFilter 允许正确反序列化 DateTime 对象
- the
msg
传递给成功回调的参数包含返回的 json。
- 您可能想要使用 URL 重写器来隐藏请求 URL 中的 .svc 标记
- 在这种情况下,WCF 服务使用 webHttp 行为,而不是enableWebScript。后者动态生成 Javascript 代理来调用服务,但您提出问题的方式看起来您并不希望这样。