jQuery调用WCF服务传递JSON对象
下面這個(gè)示例使用了WCF去創(chuàng)建一個(gè)服務(wù)端口從而能夠被ASP.Net頁(yè)面通過(guò)jQuery的AJAX方法訪問(wèn),我們將在客戶端使用Ajax技術(shù)來(lái) 與WCF服務(wù)進(jìn)行通信。這里我們僅使用jQuery去連接Web Service,而不去使用ASP.Net AJAX庫(kù),至于為什么不使用AJAX庫(kù)中,那是因?yàn)槲覀冊(cè)陧?xiàng)目中已經(jīng)使用了jQuery,而它已經(jīng)能處理全部的AJAX請(qǐng)求和所有功能,并且,如果我們 一旦使用ASP.NET AJAX庫(kù),我們也必須多包含一個(gè)超過(guò)80Kb的數(shù)據(jù)量(調(diào)試模式下會(huì)更大),但這也不是說(shuō)ASP.NET AJAX庫(kù)不實(shí)用,事實(shí)上,如果使用了相同的類庫(kù),我們能夠少寫很多的額外代碼,但這個(gè)例子就是為了說(shuō)明,在沒(méi)有一個(gè)好的客戶端代理的情況下,我們是如何 調(diào)用Web服務(wù)的。
WCF 服務(wù):
我們先創(chuàng)建一個(gè)WebSite,然后添加一個(gè)AJAX-enabled WCF Service,從而創(chuàng)建WCF服務(wù)。(請(qǐng)確保你使用了正確的.Net Framework 版本,我用的是3.5)?
在我們添加完service后,它會(huì)自動(dòng)進(jìn)入該service的后置代碼文件,Go ahead and browse around the file for a second.
首先我們要做的是找到"AspNetCompatibilityRequirements"并將其值置為 "Allowed":
[AspNetCompatibilityRequirements(?RequirementsMode?=?AspNetCompatibilityRequirementsMode.Allowed?)]???
這個(gè)屬性的設(shè)置可將我們的服務(wù)跑在ASP.NET compatibility模式,如果我們未將該值設(shè)為"Allowed",那么就無(wú)法通過(guò)ASP.Net去訪問(wèn)到該服務(wù),這個(gè)屬性是當(dāng)你添加 "AJAX-enabled WCF Service" 時(shí)自動(dòng)生成的。更多祥細(xì)請(qǐng)參看MSDN。
現(xiàn)在再來(lái)看自動(dòng)生成的后置代碼文件,我們能發(fā)現(xiàn)已經(jīng)存在了一個(gè)被標(biāo)注了"OperationContract"特性的"DoWork()" 的方法,這個(gè)方法是自動(dòng)生成的,我們將使用這個(gè)方法來(lái)完成下面的示例。我們?cè)賮?lái)為該方法添加一個(gè)"WebGet"的特性,并設(shè)"RequestFormat" 的值為 "Json." 我們?cè)賮?lái)為該方法加上另外的一個(gè)特性RequestFormat,WebGet 和Get動(dòng)詞一樣,作用于一個(gè)UriTemplate(本文不對(duì)此作進(jìn)一步討論),RequestFormat 特性可以讓我們接收J(rèn)SON格式的請(qǐng)求。
我們的 "DoWork()" 方法如下:
[OperationContract]?[WebGet(?RequestFormat=WebMessageFormat.Json?)]?
public?void?DoWork()?
{?
????//?Add?your?operation?implementation?here?
????return;?
}
?
對(duì)象的模型:
我們希望通過(guò)"DoWork()" 來(lái)傳遞一個(gè)叫“Person”的對(duì)象,那先來(lái)創(chuàng)建一個(gè)Person對(duì)象寫入到當(dāng)前類的頭部,其包含字段和屬性(Name, Age 和 the types of Shoes they own),這個(gè)類同時(shí)也作為所傳遞JSON的結(jié)構(gòu)。
[Serializable]?
[DataContract(?Namespace?=?"http://www.dennydotnet.com/",?Name?=?"Person"?)]?
public?class?Person?
{?
??? private?string?_name?=?string.Empty;?
??? private?int?_age?=?0;?
??? [DataMember(?IsRequired?=?true,?Name?=?"Name"?)]?
??? public?string?Name?
??? {?
????????get?{?return?_name;?}?
????????set?{?_name?=?value;?}?
??? }?
??? [DataMember(?IsRequired?=?true,?Name?=?"Age"?)]?
??? public?int?Age?
??? {?
????????get?{?return?_age;?}?
????????set?{?_age?=?value;?}?
??? }?
??? [DataMember(?IsRequired?=?true,?Name?=?"Shoes"?)]?
??? public?List<String>?Shoes;?
}?
?
我們已經(jīng)為 "Person”類的名稱和命名空間標(biāo)注上了契約,我們?nèi)孕枰獮閷傩允谟跀?shù)據(jù)成員特性,為每個(gè)屬性 設(shè)置"IsRequired"并具體指定其名稱。你只需要具體指定名字,如果它和屬性名不一樣。舉例來(lái)說(shuō)吧,如果你有一個(gè)屬性叫作“Level”,但你在 數(shù)據(jù)成員特性中賦值為“Rank”,現(xiàn)在我們要回去修改我們的“DoWork()”方法,去接收Person對(duì)象作為參數(shù)。具體參下面代碼塊。
[OperationContract]?[WebGet(?RequestFormat=WebMessageFormat.Json?)]?
public?void?DoWork(Person?p)?
{?
??? //?Add?your?operation?implementation?here?
??? return;?
}
?
對(duì)Web.Config文件進(jìn)行配置:?
我們僅需對(duì)web.config文件做出很小的修改就能對(duì)服務(wù)進(jìn)行訪問(wèn)了。首先加入一個(gè) serviceBehavior 用來(lái)允許Http Get請(qǐng)求,再添加一些調(diào)試選項(xiàng)幫助。代碼如下:
Below </endpointBehaviors>
<serviceBehaviors>???? <behavior?name="ServiceAspNetAjaxBehavior">?
??????? <serviceMetadata?httpGetEnabled="true"?httpGetUrl=""?/>?
??????? <serviceDebug?httpHelpPageEnabled="true"?includeExceptionDetailInFaults="true"?/>?
??? </behavior>?
</serviceBehaviors>
?
在<services>這里</services>之間,你的代碼如下:
<service?name="Service"?behaviorConfiguration="ServiceAspNetAjaxBehavior">???? <endpoint?address=""?behaviorConfiguration="ServiceAspNetAjaxBehavior"?
binding="webHttpBinding"?contract="Service"?/>?
??? <endpoint?address="mex"?binding="mexHttpBinding"?contract="IMetadataExchange"?/>?
</service>?
?
A?security note?about the following line:
?
<serviceDebug?httpHelpPageEnabled="true"?includeExceptionDetailInFaults="true"?/>?Allowing exception details can expose internal application information including personally identifiable or otherwise sensitive information. Setting the option to true is only recommended as a way to temporarily debug your service!!
你的Web.config文件修改后如下圖所示:
回到前端頁(yè)面:?
現(xiàn)在我們的服務(wù)已經(jīng)被創(chuàng)建和配置了,再來(lái)關(guān)注前端頁(yè)面部分吧(確保頁(yè)面已引用jQuery.js文件),首先來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的Json對(duì)象用于向service傳遞,我們?cè)赑erson類結(jié)構(gòu)的基礎(chǔ)上創(chuàng)建該JSON對(duì)象。?
?
如果你對(duì)JSON還不是很熟悉,我們可以把它看作一個(gè)對(duì)象,這個(gè)小工具幫助你來(lái)查看 (JsonViewer):?
我們需要使用WCF和jQuery進(jìn)行Ajax通信,下面的代碼創(chuàng)建了一個(gè)AJAX呼叫,在頭部設(shè)置了GET方式,和內(nèi)容類型為 application/json,將url的路徑置為WCF 服務(wù)的 svc 文件,并在其后加上/和所要執(zhí)行方法的名稱,在這里我們要調(diào)用的是DoWork()方法,data是用來(lái)傳遞參數(shù),為了讓jQuery不去自動(dòng)處理我們的 數(shù)據(jù),將processData設(shè)為false,我們還加入了對(duì)success和error的處理,以更多的了解AJAX執(zhí)行完之后的處理過(guò)程。
?
function?sendAJAX(data)?{??? ?$.ajax({?
?? ? ? ?type:?"GET",?
?? ? ? ?contentType:?"application/json",?
?? ? ? ?url:?"Service.svc/DoWork",?
?? ? ? ?data:?data,?
?? ? ? ?processData:?false,?
?? ? ? ?success:?function(msg){?
?? ? ? ? ? ? ? ?alert(?"Data?Saved!"?);?
?? ? ? ?},?
?? ? ? ?error:function(XMLHttpRequest,?textStatus,?errorThrown){?
?? ? ? ? ? ? ? ?alert(?"Error?Occured!"?);?
?? ? ? ?}?
?? ?});?
}
?
然而很不幸運(yùn),這里有一個(gè)小的問(wèn)題,我們必須發(fā)送真正的JSON字符串,作為參數(shù)傳遞。但還沒(méi)有簡(jiǎn)單的方法讓JSON對(duì)象轉(zhuǎn)換為字符串,如果你試了data.toString(),得到的會(huì)是一個(gè) "[object Object]"值。這不是我們想要的。?
所以在這里我們要修改方法使得它能將JSON轉(zhuǎn)換成字符串。
Note*?The JSON de/serialization handles Date/Time in a specific way. The json2string function below does not take this into account. I'm sure there are some implementations out there which will work with ASP.NET AJAX but this one does not. For more information on this you can go?here.
Update [4/11/08]:?The javascript below has a few issues so it's been suggested that you should use the?JSON.org?version to "stringify" your object. You can download the script?from here.
Update [4/25/08]:?Rick Strahl has modified the JSON.org script so that it will properly create the dates to work with ASP.NET AJAX (read his post)
function?json2string(strObject)?{?var?c,?i,?l,?s?=?'',?v,?p;?
switch?(typeof?strObject)?{?
case?'object':?
if?(strObject)?{?
if?(strObject.length?&&?typeof?strObject.length?==?'number')?{?
for?(i?=?0;?i?<?strObject.length;?++i)?{?
?????v?=?json2string(strObject[i]);?
if?(s)?{?
??????s?+=?',';?
?????}?
?????s?+=?v;?
????}?
return?'['?+?s?+?']';?
???}?else?if?(typeof?strObject.toString?!=?'undefined')?{?
for?(i?in?strObject)?{?
?????v?=?strObject[i];?
if?(typeof?v?!=?'undefined'?&&?typeof?v?!=?'function')?{?
??????v?=?json2string(v);?
if?(s)?{?
???????s?+=?',';?
??????}?
??????s?+=?json2string(i)?+?':'?+?v;?
?????}?
????}?
return?'{'?+?s?+?'}';?
???}?
??}?
return?'null';?
case?'number':?
return?isFinite(strObject)???String(strObject)?:?'null';?
case?'string':?
??l?=?strObject.length;?
??s?=?'"';?
for?(i?=?0;?i?<?l;?i?+=?1)?{?
???c?=?strObject.charAt(i);?
if?(c?>=?'?')?{?
if?(c?==?'//'?||?c?==?'"')?{?
?????s?+=?'//';?
????}?
????s?+=?c;?
???}?else?{?
switch?(c)?{?
case?'/b':?
??????s?+=?'//b';?
break;?
case?'/f':?
??????s?+=?'//f';?
break;?
case?'/n':?
??????s?+=?'//n';?
break;?
case?'/r':?
??????s?+=?'//r';?
break;?
case?'/t':?
??????s?+=?'//t';?
break;?
default:?
??????c?=?c.charCodeAt();?
??????s?+=?'//u00'?+?Math.floor(c?/?16).toString(16)?+?
???????(c?%?16).toString(16);?
????}?
???}?
??}?
return?s?+?'"';?
case?'boolean':?
return?String(strObject);?
default:?
return?'null';?
}?
}?
?
現(xiàn)在我們有一個(gè)方法可以將JSON對(duì)象轉(zhuǎn)成我們所需要的字符串,現(xiàn)在我們回過(guò)頭去修改我們之前定義的 "mydata" 變量,我們應(yīng)當(dāng)按下面去應(yīng)用所寫的json2string方法。
var?mydata?=?{?"Name":"Denny",?"Age":23,?"Shoes":["Nike","Osiris","Etnies"]?};?var?jsonStr?=?"p="?+?json2string(mydata);?
?
注意在下面我準(zhǔn)備了"p=" 字符在我們的JSON字符串中,“p”對(duì)應(yīng)于"DoWork()" 方法中的參數(shù),當(dāng)我們將參數(shù)改名為"Dude" ( 例如DoWork(Person?Dude) )時(shí),我們也必須將此處替換為"Dude="
現(xiàn)在我們準(zhǔn)備好了查詢字符串,我們參看到我們?nèi)绾握{(diào)用服務(wù):?
http://www.dennydotnet.com/Service.svc/DoWork/?p={ "Name":"Denny", "Age":23, "Shoes":["Nike","Osiris","Etnies"] }
?
你將接收到一個(gè)已經(jīng)為URL編碼處理過(guò)的值,如下:?
http://www.dennydotnet.com/Service.svc/DoWork/?p=%7b+%22Name%22%3a%22Denny%22%2c+%22Age%22%3a23%2c+%22Shoes%22%3a%5b%22Nike%22%2c%22Osiris%22%2c%22Etnies%22%5d+%7d%3b
緊接著我們?nèi)フ{(diào)用"SendAjax()" javascript 方法,現(xiàn)在能夠調(diào)試我們的服務(wù)并驗(yàn)證數(shù)據(jù)是否被傳遞到服務(wù)。如下圖
?
現(xiàn)在你僅需要在DoWork()方法里實(shí)現(xiàn)自己的邏輯。注意無(wú)論你如何怎么去做 在WCF的服務(wù)端,它已經(jīng)為你做好了。?
現(xiàn)在你僅需實(shí)現(xiàn)一些異常管理以確定你不會(huì)得到一些非法數(shù)據(jù),或者添加一些驗(yàn)證,那就留給你自己吧...
本文轉(zhuǎn)自左正博客園博客,原文鏈接:http://www.cnblogs.com/soundcode/p/4110132.html,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的jQuery调用WCF服务传递JSON对象的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JDK工具jstatd用法详解(转)
- 下一篇: javascript 卸载事件(on