WCF返回JSON与传入JSON(普通参数或对象)
博客转移到:http://iyf.cc/archives/56
这是我在项目开发中遇到的,需要传入一个有很多参数的wcf方法,因为使用js来调用,以前一直的做法是方法写成多个变量,传入json就可以了,但是参数太多了呢,而且也写了相关的数据契约类,那为啥不传入对象呢.动手一试,结果失败了,网上到处也没找到信息,只好自己来了.本文中不讲基础,只说核心,如果不明白的可以留言.
一:WCF返回的JSON.
一般使用了数据契约后,返回的JSON就是带有数据类型的.
{"d":{"__type":"NNum:#","Name":"组织"}}
这是一个例子,d是名称空间,所有wcf都有这个,eval(data.d)就可以去掉了.里面的__type表示了数据类型,后面相关的数据.
二:调用WCF传入参数(普通)
要想调用一个类似于.
[OperationContract]
[WebInvoke]
public void aaa(int dsd)
这样的方法,可以使用[WebInvoke]
public void aaa(int dsd)
jQuery.ajax({
type: "POST",
contentType: "application/json",
url: "地址",
dataType: 'json',
data: '{"dsd":1}',
success: function (de) {
eval(de.a);
});
type: "POST",
contentType: "application/json",
url: "地址",
dataType: 'json',
data: '{"dsd":1}',
success: function (de) {
eval(de.a);
});
这样的方式,我写了一个JS的小库大家可以看看
function webSer(url, func, data, ca) {
data = GetString(data == void 0 ? "" : data);
ca = ca == void 0 ? false : ca;
jQuery.ajax({
type: "POST",
cache: ca,
contentType: "application/json",
url: url,
dataType: 'json',
data: data,
success: function (de) {
func(de.d == "n" ? null : ClearD(de));
},
error: function (data) {
alert(data.responseText);
}
});
}
function GetString(data) {
if (typeof data == "object") {
return JSON.stringify(data);
} else {
return data;
}
}
function ClearD(data) {
return data.d;
}
data = GetString(data == void 0 ? "" : data);
ca = ca == void 0 ? false : ca;
jQuery.ajax({
type: "POST",
cache: ca,
contentType: "application/json",
url: url,
dataType: 'json',
data: data,
success: function (de) {
func(de.d == "n" ? null : ClearD(de));
},
error: function (data) {
alert(data.responseText);
}
});
}
function GetString(data) {
if (typeof data == "object") {
return JSON.stringify(data);
} else {
return data;
}
}
function ClearD(data) {
return data.d;
}
这个库需要jquery和在IE8一下的json2支持,引入json2可以用这个代码.
<!--[if lt IE 7]>
<script type="text/javascript" src="/Scripts/json2.js"></script>
<![endif]-->
<script type="text/javascript" src="/Scripts/json2.js"></script>
<![endif]-->
那么调用就是
function end(data)
{
}
webSer("wcf的地址",end,{"dsd":1})
{
}
webSer("wcf的地址",end,{"dsd":1})
{"dsd":1} 其中dsd是参数的名称,后面是值.
三: 调用WCF传入参数(对象)
最后来说说怎么让wcf能够成功反序列化对象吧,有2个重点.
1.":{"__type":"NNum:#"}这里的命名空间,NNum是类型的名称,#后面加上你的命名空间的名称,至于这个#是什么,我引用微软的解释.
减小类型提示的大小 为了减小 JSON 消息的大小,默认的数据协定命名空间前缀 (http://schemas.datacontract.org/2004/07/) 已替换为“#”字符。(为了使这一替换具备可逆性,此操作采用了一项转义规则:如果命名空间以“#”或“\”字符开头,将为它们追加另一个“\”字符。)这样,如果“Circle”是 .NET 命名空间“MyApp.Shapes”中的一个类型,则其默认的数据协定命名空间将是 http://schemas.datacontract.org/2004/07/MyApp。下面是 Shapes 及其 JSON 表示形式。 {"__type":"Circle:#MyApp.Shapes","x":50,"y":70,"radius":10}
执行反序列化时,既能识别截断的名称 (#MyApp.Shapes),也能识别完整的名称 (http://schemas.datacontract.org/2004/07/MyApp.Shapes)。
执行反序列化时,既能识别截断的名称 (#MyApp.Shapes),也能识别完整的名称 (http://schemas.datacontract.org/2004/07/MyApp.Shapes)。
2.就是参数格式了.
[OperationContract]
[WebInvoke]
public void SetDisputSearch(test dsd)
{
int i = dsd.i;
}
[DataContract]
public class test
{
[DataMember]
public int i { set; get; }
[DataMember]
public int? l { set; get; }
[DataMember]
public int? k { set; get; }
}
上面这样的方法怎么调用呢,这就是本文的重点了,大家一看就明白了.
webSer("/Server/Search.svc/SetDisputSearch", null, { "dsd": { "__type": "test:#", "i": 1,"k":0} });
{ "dsd": { "__type": "test:#", "i": 1,"k":0} }其中dsd就是参数名了.后面就是这个对象的信息了.在这个例子里面"__type": "test:#", 不要也能成功的.