日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

绛河 初识WCF5

發(fā)布時(shí)間:2023/12/13 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 绛河 初识WCF5 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
然后我們?cè)?span style="color:#0000ff;"><Client>中添加一個(gè)終結(jié)點(diǎn),這個(gè)是客戶端的終結(jié)點(diǎn),我們前面曾經(jīng)提過,通信實(shí)際上發(fā)生在兩個(gè)終結(jié)點(diǎn)間,客戶端也有個(gè)終結(jié)點(diǎn),然而請(qǐng)求總是從客戶端首先發(fā)起,所以終結(jié)點(diǎn)地址應(yīng)該填寫為服務(wù)端終結(jié)點(diǎn)的地址讓客戶端來尋址,但是服務(wù)協(xié)定要客戶端本地是有的,所以這個(gè)要寫本地定義的那個(gè)協(xié)定的完全限定名:

?

引用http://blog.csdn.net/songyefei/article/details/7389186

第五篇 再探通信--ClientBase

?

在上一篇中,我們拋開了服務(wù)引用和元數(shù)據(jù)交換,在客戶端中手動(dòng)添加了元數(shù)據(jù)代碼,并利用通道工廠ChannelFactory<>類創(chuàng)建了通道,實(shí)現(xiàn)了和服務(wù)端的通信。然而,與服務(wù)端通信的編程模型不只一種,今天我們來學(xué)習(xí)利用另外一個(gè)服務(wù)類ClientBase<>來完成同樣的工作,了解了這個(gè)類的使用方法,我們對(duì)服務(wù)引用中的關(guān)鍵部分就能夠理解了。

?

?

?

ClientBase<>類也是一個(gè)泛型類,接受服務(wù)協(xié)定作為泛型參數(shù),與ChannelFactory<>不同的是,這個(gè)類是一個(gè)基類,即抽象類,是不能實(shí)例化成對(duì)象直接使用的,我們需要自己寫一個(gè)類來繼承這個(gè)類,我們新寫的類實(shí)例化出來就是客戶端代理了,這個(gè)對(duì)象可以調(diào)用基類的一些受保護(hù)的方法來實(shí)現(xiàn)通信。ClientBase<>為我們封裝的很好,我們只需要寫個(gè)新類來繼承他就可以了,通信的很多部分他都替我們做好了,比如我們不用進(jìn)行去創(chuàng)建通道和打開通道的操作,直接調(diào)用協(xié)定方法就可以了。這也是服務(wù)引用和其他元數(shù)據(jù)生成工具(如svcutil)使用這個(gè)類來構(gòu)造客戶端代理的原因。

?

?

?

我們一邊動(dòng)手一邊學(xué)習(xí)

?

?

?

1. 建立客戶端程序

?

我們依然不用服務(wù)引用,完全手寫,這次還是建立一個(gè)控制臺(tái)應(yīng)用程序作為客戶端。

?

2. 添加必要的引用

?

我們用到的ClientBase<>類在System.ServiceModel程序集中,因此,要添加這個(gè)程序集的引用,同時(shí)在program.cs中添加using語句

  • using?System.ServiceModel;?
  • 這一步應(yīng)該很熟了,如果有疑問,返回前幾篇溫習(xí)一下。

    因?yàn)闆]有使用服務(wù)引用,客戶端現(xiàn)在沒有任何元數(shù)據(jù)的信息,我們要來手寫。首先把服務(wù)協(xié)定寫進(jìn)去。這個(gè)再熟悉不過了(寫在Program類后面):

    [ServiceContract] public interface IHelloWCF { [OperationContract] string HelloWCF(); }

    4. 編寫客戶端代理類

    上面已經(jīng)提到,我們要自己寫一個(gè)新類來繼承ClientBase<>基類,這樣這個(gè)新類就是代理類了,同時(shí),為了能夠用代理類直接調(diào)用服務(wù)協(xié)定的方法,我們還要讓代理類實(shí)現(xiàn)服務(wù)協(xié)定的接口,注意,繼承要寫在前面,實(shí)現(xiàn)接口要寫在后面。我們把這個(gè)類起名為HelloWCFClient。

    public class HelloWCFClient : ClientBase<IHelloWCF>, IHelloWCF { }

    ClientBase<>有許多的構(gòu)造函數(shù),接受不同種類的參數(shù)來創(chuàng)建代理類對(duì)象,其實(shí)這些參數(shù)都是元數(shù)據(jù)信息,剛才我們已經(jīng)通過泛型參數(shù)傳遞給基類服務(wù)協(xié)定這個(gè)元數(shù)據(jù)了,現(xiàn)在基類還需要綁定和終結(jié)點(diǎn)地址這兩個(gè)元數(shù)據(jù)才能正確創(chuàng)建連接,所以我們繼承的新類應(yīng)該把這個(gè)構(gòu)造函數(shù)給覆載一下接受這兩種元數(shù)據(jù)參數(shù)并傳遞給基類。

    public class HelloWCFClient : ClientBase<IHelloWCF>, IHelloWCF { public HelloWCFClient(System.ServiceModel.Channels.Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { } }

    我們看到這個(gè)新建的構(gòu)造函數(shù)什么也沒做,只是接受了兩個(gè)參數(shù),一個(gè)是綁定,一個(gè)是終結(jié)點(diǎn)地址,然后直接調(diào)用基類(也就是ClientBase<>)的構(gòu)造函數(shù),把這個(gè)兩個(gè)參數(shù)傳遞了上去。其實(shí)工作都是ClientBase<>做的,我們新建的類就是個(gè)傳話的,要不然怎么叫代理呢,他什么活都不干。

    既然我們實(shí)現(xiàn)了服務(wù)協(xié)定接口,當(dāng)然要實(shí)現(xiàn)接口的方法了。下面我們把方法的實(shí)現(xiàn)寫下來:

    public class HelloWCFClient : ClientBase<IHelloWCF>, IHelloWCF { public HelloWCFClient(System.ServiceModel.Channels.Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public string HelloWCF() { return base.Channel.HelloWCF(); } }

    別忘了你的處境,凡人!我們這是在客戶端啊,怎么可能有服務(wù)協(xié)定呢?這個(gè)可以有,但是這個(gè)實(shí)現(xiàn)不是我們?cè)谧?#xff0c;而是要和服務(wù)端通信讓服務(wù)端做,這里可以看到代理鮮明的特點(diǎn)了,代理類雖然實(shí)現(xiàn)了服務(wù)協(xié)定的方法,但是在方法中,他調(diào)用了基類(就是ClientBase<>)上的通道,并通過通道調(diào)用了了協(xié)定方法。此時(shí),ClientBase<>已經(jīng)為我們建立好與服務(wù)端的通道了,而且是用服務(wù)協(xié)定建立的,我們當(dāng)然可以在通道上調(diào)用服務(wù)協(xié)定的方法。所以調(diào)用代理類對(duì)象的HelloWCF()的過程是代理類委托基類在已經(jīng)建立好的服務(wù)協(xié)定通道上調(diào)用協(xié)定方法,并從服務(wù)端獲得返回值,然后再返回給代理類對(duì)象的調(diào)用者。狗腿啊狗腿。

    5. 編寫程序主體

    代理類已經(jīng)寫完了,我們現(xiàn)在開始寫程序的主體,讓我們來到Program的Main函數(shù)中。

    還是有一些準(zhǔn)備要做,還差兩個(gè)元數(shù)據(jù)呢,對(duì)了,就是綁定和地址。和上一篇一樣,我們先建立這個(gè)兩個(gè)元數(shù)據(jù)的對(duì)象備用:

    WSHttpBinding binding = new WSHttpBinding(); EndpointAddress remoteAddress = new EndpointAddress("http://localhost/IISService/HelloWCFService.svc");

    接下來就要建立我們的代理類對(duì)象了,new一個(gè)出來吧:

    HelloWCFClient client = new HelloWCFClient(binding, remoteAddress);

    把我們剛剛建立的兩個(gè)元數(shù)據(jù)對(duì)象作為參數(shù)傳遞進(jìn)去。

    ?

    接下來就可以調(diào)用服務(wù)協(xié)定方法了:

    string result = client.HelloWCF();


    別忘了關(guān)閉通道,ClientBase<>很貼心的為我們準(zhǔn)備了這個(gè)方法,不用再做強(qiáng)制類型轉(zhuǎn)換什么的了(見前一篇)。

    client.Close();?

    以下是Program.cs的全部代碼:

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace ConsoleClient { class Program { static void Main(string[] args) { WSHttpBinding binding = new WSHttpBinding(); EndpointAddress remoteAddress = new EndpointAddress("http://localhost/IISService/HelloWCFService.svc"); HelloWCFClient client = new HelloWCFClient(binding, remoteAddress); string result = client.HelloWCF(); client.Close(); Console.WriteLine(result); Console.ReadLine(); } } [ServiceContract] public interface IHelloWCF { [OperationContract] string HelloWCF(); } public class HelloWCFClient : ClientBase<IHelloWCF>, IHelloWCF { public HelloWCFClient(System.ServiceModel.Channels.Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public string HelloWCF() { return base.Channel.HelloWCF(); } } }

    6. 再展開一點(diǎn)點(diǎn)

    這樣看上去已經(jīng)挺成功了,我們現(xiàn)在再打開服務(wù)引用的reference.cs代碼,看看是不是大部分都看得懂了?監(jiān)管有些地方他寫的可能有些復(fù)雜,比如描述協(xié)定的屬性參數(shù)啊,代理類更多的構(gòu)造函數(shù)啊,但是核心的就是我們剛剛寫的部分,那一大堆wsdl什么的其實(shí)都不是核心,不信的話你把他們都刪掉,就留一個(gè)reference.cs看看還好不好用?那一堆東西也不是沒用就是現(xiàn)在自己看起來還蠻復(fù)雜的,我們到后面一點(diǎn)點(diǎn)學(xué)習(xí)。

    ?

    我們仔細(xì)看服務(wù)引用的reference.cs代碼,有一樣?xùn)|西是我們有而他沒有的,那就是對(duì)終結(jié)點(diǎn)地址和綁定的建立,而且在使用服務(wù)引用的時(shí)候我們也沒有提供之兩樣?xùn)|西,直接掉服務(wù)協(xié)定方法就行了(見第一篇),那么服務(wù)引用是從哪里找到這兩個(gè)關(guān)鍵的元數(shù)據(jù)元素呢?

    ?

    就在配置文件里,我們做的客戶端還沒有配置文件,我們可以把這兩個(gè)元素都放在配置文件里,這樣就可以避免硬編碼了。

    ?

    為我們的控制臺(tái)應(yīng)用程序添加一個(gè)應(yīng)用程序配置文件。方法是右鍵點(diǎn)擊項(xiàng)目->添加->新建項(xiàng)->應(yīng)用程序配置文件。保持默認(rèn)名稱app.config。

    打開來看,里面沒寫什么實(shí)際的內(nèi)容:

    <?xml version="1.0" encoding="utf-8" ?> <configuration> </configuration>

    我們對(duì)配置服務(wù)應(yīng)該不陌生,如果忘記了,翻回到第二篇去回顧一下。

    首先還是要添加<System.ServiceModel>節(jié),無論是服務(wù)端還是客戶端,只要是WCF的服務(wù)配置都要在這個(gè)節(jié)里面:

    <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> </system.serviceModel> </configuration>

    在這里我們要配置的是客戶端,所以我們不添加<Services>節(jié)了,而改成<Client>:

    <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> </client> </system.serviceModel> </configuration>

    ?

    如果你忘記了我們?cè)诘谌信渲玫腎IS服務(wù)的內(nèi)容,可能稍有迷惑,這里的地址看上去是個(gè)服務(wù)地址而不是終結(jié)點(diǎn)地址,這是因?yàn)槲覀冊(cè)贗IS中把終結(jié)點(diǎn)地址設(shè)置為了空字符串,此時(shí)服務(wù)地址就是終結(jié)點(diǎn)地址了。注意看后面的contract,他的完全限定名的命名空間是客戶端程序的命名空間ConsoleClient,這也表示這個(gè)類型是定義在本地的,不要搞錯(cuò)了。

    ?

    保存,配置已經(jīng)寫完了,你如果看服務(wù)引用為我們生成的配置會(huì)看到一堆東西,實(shí)際上核心的就是這些。

    ?

    既然我們已經(jīng)在配置中聲明了綁定和終結(jié)點(diǎn)地址,在代碼中就不再需要了。

    首先我們修改一下代理類,為他提供一個(gè)沒有參數(shù)的構(gòu)造函數(shù),否則在new他的時(shí)候他會(huì)非管我們要兩個(gè)參數(shù)。

    public HelloWCFClient() : base() { }

    還是什么也不做,直接調(diào)基類的無參構(gòu)造函數(shù)。

    ?

    然后修改一下Main函數(shù),去掉終結(jié)點(diǎn)對(duì)象和地址對(duì)象的聲明,并用無參構(gòu)造函數(shù)來new 代理類的實(shí)例:

    static void Main(string[] args) { HelloWCFClient client = new HelloWCFClient(); string result = client.HelloWCF(); client.Close(); Console.WriteLine(result); Console.ReadLine(); }

    F5運(yùn)行一下,結(jié)果如一吧!

    到這里已經(jīng)和服務(wù)引用的感覺基本一樣了,我們已經(jīng)寫出了服務(wù)引用的核心部分。

    以下是修改后的Program.cs完整代碼:

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace ConsoleClient { class Program { static void Main(string[] args) { HelloWCFClient client = new HelloWCFClient(); string result = client.HelloWCF(); client.Close(); Console.WriteLine(result); Console.ReadLine(); } } [ServiceContract] public interface IHelloWCF { [OperationContract] string HelloWCF(); } public class HelloWCFClient : ClientBase<IHelloWCF>, IHelloWCF { public HelloWCFClient() : base() { } public HelloWCFClient(System.ServiceModel.Channels.Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public string HelloWCF() { return base.Channel.HelloWCF(); } } }

    7. 總結(jié)

    通過本篇的學(xué)習(xí),我們熟悉了另一種與服務(wù)端通信的辦法,即通過ClientBase<>派生代理類的方法,這種方法實(shí)際上就是服務(wù)引用使用的方法,可以說我們已經(jīng)在最簡單級(jí)別上手寫了一個(gè)服務(wù)引用的實(shí)現(xiàn)。

    ?

    使用ChannelFactory<>和ClientBase<>都可以實(shí)現(xiàn)與服務(wù)端的通信,這是類庫支持的最高層次的通訊方法了,其實(shí)還有更底層的通道通信方法,我們現(xiàn)在就不再深入了。而選擇這兩種方法完全取決于開發(fā)人員,有人喜歡工廠,有人喜歡代理類。既然我們都已經(jīng)掌握了,就隨意選擇吧。

    ?

    至此,我們對(duì)通信有了一個(gè)基本的了解,只能算一個(gè)初探吧。然而我相信這一次的小小深入會(huì)對(duì)我們今后的學(xué)習(xí)帶來大大的幫助的。

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/janghe/p/7594217.html

    總結(jié)

    以上是生活随笔為你收集整理的绛河 初识WCF5的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。