.NET Framework讓W(xué)eb服務(wù)的創(chuàng)建變得實(shí)在是很簡(jiǎn)單,尤其是在你使用Visual Studio .NET進(jìn)行開發(fā)的時(shí)候。你看起來很普通的.NET代碼文件里召喚W(wǎng)eb服務(wù)精靈的咒語(yǔ)就只需要十一個(gè)字符:[WebMethod]。有了修飾類方法的[WebMethod]屬性以及.asmx文件所參照的類,ASP.NET會(huì)在WSDL里生成一個(gè)完整的服務(wù)描述,并立即開始對(duì)客戶提供服務(wù)。
但是,由于對(duì)應(yīng)用程序有各自獨(dú)特要求,所以大多數(shù)開發(fā)人員一般都無(wú)法停在[WebMethod]自動(dòng)生成的代碼處。開發(fā)人員添加的最明顯的其它屬性可能就是[WebService],你可以通過它提供詳細(xì)的服務(wù)描述,以及,最重要的是,能夠修改http://tempuri.org里的命名空間,這個(gè)網(wǎng)址由ASP.NET自動(dòng)分配,也是你在后來從瀏覽器訪問Web服務(wù)時(shí)會(huì)抱怨的東西。在本文中,我不會(huì)講這些簡(jiǎn)單的內(nèi)容,而會(huì)去考慮一些更加復(fù)雜的改變,你可能會(huì)需要這些改變來仔細(xì)修剪ASP.NET為你匆忙生成的WSDL和SOAP。
缺少SOAP報(bào)頭
我們第一個(gè)例子要解決ASP.NET在缺省狀態(tài)下不會(huì)生成SOAP報(bào)頭元素的問題。如果需要用戶向你傳遞諸如用戶名和密碼之類的信息,這些信息就應(yīng)該同SOAP主體里出現(xiàn)的功能請(qǐng)求分開,而放在報(bào)頭里。你需要告訴.NET這個(gè)報(bào)頭應(yīng)該是什么樣的,哪些信息會(huì)包含這個(gè)報(bào)頭,以及它是否是任何那些信息絕對(duì)必需的。首先要在和你的主Web服務(wù)類相同的命名空間里創(chuàng)建一個(gè)小類。
這個(gè)新的類將會(huì)代表報(bào)頭元素,而且它必須:
繼承System.Web.Services.Protocols.SoapHeader
由公共訪問修改器確定其范圍。
你可以把任何自己所希望的公共字段放到這個(gè)類里。你還需要在主Web服務(wù)類里創(chuàng)建這個(gè)報(bào)頭類的公共實(shí)例變量。你可以用自己希望的名字命名這個(gè)實(shí)例變量;在Listing A里我把它叫做auth。不要包括進(jìn)任何用于這個(gè)變量的實(shí)例化代碼;ASP.NET很會(huì)做這件事。
在創(chuàng)建了能夠用作SOAP報(bào)頭元素的類和實(shí)例變量以后,你現(xiàn)在需要告訴ASP.NET哪個(gè)Web服務(wù)方法要使用報(bào)頭。只需使用System.Web.Services.Protocols命名空間的[SoapHeader]屬性來修飾那些你希望在SOAP信息里包含有報(bào)頭的方法。注意[SoapHeader]屬性的第一個(gè)特性是特殊報(bào)頭類的實(shí)例變量名。賦予“方向”特性的值表明只有請(qǐng)求(到來信息)會(huì)使用這個(gè)報(bào)頭,而且“必需的”特性也要求其使用;不包含必需報(bào)頭的請(qǐng)求信息會(huì)導(dǎo)致服務(wù)器返回SOAP錯(cuò)誤。如果現(xiàn)在創(chuàng)建這個(gè)服務(wù)并使用其.asmx文件查看示例SOAP,你會(huì)看到請(qǐng)求信息所包含的報(bào)頭元素還有兩個(gè)子元素,它們每一個(gè)都代表特殊報(bào)頭類的一個(gè)公共字段。
由于已經(jīng)告訴了ASP.NET會(huì)有報(bào)頭,所以你可以對(duì)自己的Web方法實(shí)際地使用代碼里的實(shí)例變量。
更多描述特性
在使用有點(diǎn)神秘的參數(shù)名超近道的時(shí)侯,你可能還想對(duì)你的客戶更好一些,并把更加詳細(xì)的描述特性放到[WebMethod]屬性里。這讓W(xué)SDL文件更大,但是,更加重要的是,SOAP包更小;這是個(gè)不錯(cuò)的折衷方案。
當(dāng)你瀏覽.NET Framework文檔看看有沒有其他的方法操控SOAP和WSDL的時(shí)候,有幾件事要記住。首先,要注意在三個(gè)不同命名空間里有一些屬性會(huì)被用到:
System.Web.Services
System.Web.Services.Protocols
System.Xml.Serialization
這就意味著你可以在Web服務(wù)生命周期的不同階段操控事件,這在尋求特定解決方案的時(shí)候會(huì)非常重要。例如,你也許會(huì)發(fā)現(xiàn)和SOAP相關(guān)的屬性類都不能完成一些事情,但是你可以試一下XML串行化屬性,看看是否能夠在那一層操控從而實(shí)現(xiàn)你的目標(biāo)。在細(xì)讀這些命名空間的時(shí)候,你要尤其小心名稱以“Attribute”結(jié)尾的類。每個(gè)打了方括號(hào)的屬性都和這些類的其中一個(gè)相對(duì)應(yīng);這種情形不僅適用于和Web服務(wù)相關(guān)的屬性,還適用于所有的修飾屬性。例如,[WebMethod]修飾屬性其實(shí)就是System.Web.Services.WebMethodAttribute類。你在類的文檔里看到的公共特性也可以放到匹配修飾屬性的圓括號(hào)里。
來一點(diǎn)點(diǎn)優(yōu)雅
正如我先前所示的那樣,你可以以自己希望的方式塑造WSDL和SOAP,而不需要訴諸于暴力方法,這會(huì)導(dǎo)致要在你的代碼里使用XmlWriter類直接執(zhí)行序列化。上面的例子大量地使用了帶有方括號(hào)的修飾屬性,這為引導(dǎo)ASP.NET創(chuàng)建這些信息提供了一種優(yōu)雅的方式。有了可以自如使用的屬性,你可以讓代碼保持自己所希望的風(fēng)格,而同時(shí)以一種為Web服務(wù)量體裁衣的方式向外部世界展示公共界面。
聯(lián)系客服