博客转移到: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:#", 不要也能成功的.