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