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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[老老实实学WCF] 第二篇 配置WCF

發(fā)布時間:2025/3/20 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [老老实实学WCF] 第二篇 配置WCF 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

老老實實學WCF

第二篇 配置WCF

?

在上一篇中,我們在一個控制臺應用程序中編寫了一個簡單的WCF服務并承載了它。先回顧一下服務端的代碼:

?

[csharp] view plaincopyprint?
  • using?System;??
  • using?System.Collections.Generic;??
  • using?System.Linq;??
  • using?System.Text;??
  • ??
  • using?System.ServiceModel;??
  • using?System.ServiceModel.Description;??
  • ??
  • namespace?HelloWCFService??
  • {??
  • ????class?Program??
  • ????{??
  • ????????static?void?Main(string[]?args)??
  • ????????{??
  • ????????????Uri?baseAddress?=?new?Uri("http://localhost:8000/MyService");??
  • ??
  • ????????????ServiceHost?host?=?new?ServiceHost(typeof(HelloWCFService),?baseAddress);??
  • ??
  • ????????????host.AddServiceEndpoint(typeof(IHelloWCFService),?new?WSHttpBinding(),?"HelloWCFService");??
  • ??
  • ????????????ServiceMetadataBehavior?smb?=?new?ServiceMetadataBehavior();??
  • ????????????smb.HttpGetEnabled?=?true;??
  • ????????????host.Description.Behaviors.Add(smb);??
  • ??
  • ????????????host.Open();??
  • ??
  • ????????????Console.WriteLine("Service?is?Ready");??
  • ????????????Console.WriteLine("Press?Any?Key?to?Terminate...");??
  • ????????????Console.ReadLine();??
  • ??
  • ????????????host.Close();??
  • ??????????????
  • ????????}??
  • ????}??
  • ??
  • ????[ServiceContract]??
  • ????interface?IHelloWCFService??
  • ????{??
  • ????????[OperationContract]??
  • ????????string?HelloWCF();??
  • ????}??
  • ??
  • ????public?class?HelloWCFService?:?IHelloWCFService??
  • ????{??
  • ????????public?string?HelloWCF()??
  • ????????{??
  • ????????????return?"Hello?WCF!";??
  • ????????}??
  • ????}??
  • }??
  • using System; using System.Collections.Generic; using System.Linq; using System.Text;using System.ServiceModel; using System.ServiceModel.Description;namespace HelloWCFService {class Program{static void Main(string[] args){Uri baseAddress = new Uri("http://localhost:8000/MyService");ServiceHost host = new ServiceHost(typeof(HelloWCFService), baseAddress);host.AddServiceEndpoint(typeof(IHelloWCFService), new WSHttpBinding(), "HelloWCFService");ServiceMetadataBehavior smb = new ServiceMetadataBehavior();smb.HttpGetEnabled = true;host.Description.Behaviors.Add(smb);host.Open();Console.WriteLine("Service is Ready");Console.WriteLine("Press Any Key to Terminate...");Console.ReadLine();host.Close();}}[ServiceContract]interface IHelloWCFService{[OperationContract]string HelloWCF();}public class HelloWCFService : IHelloWCFService{public string HelloWCF(){return "Hello WCF!";}} }

    所有的這些代碼都寫在program.cs中,干凈清爽。

    ?

    我們稍微審視一下這段程序會發(fā)現(xiàn),我們用了很多的代碼來定制服務的特性,例如基地址、終結點、綁定、行為等。這些都叫做配置。而真正對服務的本身的定義是很少的(主邏輯就是返回一個字符串而已),因此我們不難看出,WCF的編程中配置占了很大的比重。

    ?

    WCF的配置選項是很多的,我們這里只考慮最簡單的情況。我們在定義和實現(xiàn)了服務協(xié)定后,至少應該做哪些配置才能讓服務運行起來呢?

    (1) 依據(jù)服務實現(xiàn)類配置一個服務(ServiceHost)。

    (2) 指定一個基地址(如果終結點中指定了絕對地址,這步可以省略)。

    (3) 建立一個終結點,并為其指定地址、綁定和服務協(xié)定。

    (4) 建立一個元數(shù)據(jù)交換終結點。

    (5) 為服務添加一個行為來啟用元數(shù)據(jù)交換。

    雖然在.Net 4.0下微軟提供了簡化配置,我們甚至可以一行配置都不做,但是為了搞清楚配置的基本原理,我們暫時不考慮簡化配置的情況。

    ?

    以下這些配置是我們必須要做的,我們從代碼中可以看到以上幾種配置相應語句:

    ?

    建立基地址:

    [csharp] view plaincopyprint?
  • Uri?baseAddress?=?new?Uri("http://localhost:8000/MyService");??
  • Uri baseAddress = new Uri("http://localhost:8000/MyService");

    建立服務:

    [csharp] view plaincopyprint?
  • ServiceHost?host?=?new?ServiceHost(typeof(HelloWCFService),?baseAddress);??
  • ServiceHost host = new ServiceHost(typeof(HelloWCFService), baseAddress);

    建立終結點并指定地址、綁定和服務協(xié)定:

    [csharp] view plaincopyprint?
  • host.AddServiceEndpoint(typeof(IHelloWCFService),?new?WSHttpBinding(),?"HelloWCFService");??
  • host.AddServiceEndpoint(typeof(IHelloWCFService), new WSHttpBinding(), "HelloWCFService");

    添加元數(shù)據(jù)交換終結點并添加啟用元數(shù)據(jù)交換行為

    [csharp] view plaincopyprint?
  • ServiceMetadataBehavior?smb?=?new?ServiceMetadataBehavior();??
  • smb.HttpGetEnabled?=?true;??
  • host.Description.Behaviors.Add(smb);??
  • ServiceMetadataBehavior smb = new ServiceMetadataBehavior();smb.HttpGetEnabled = true;host.Description.Behaviors.Add(smb);

    看上去清楚明白,但是只是看上去很美,這樣的配置方式存在弊端,例如基地址,如果當服務部署之后遷移了服務器,基地址發(fā)生變化,我們必須修改源程序并重新編譯重新部署才能實現(xiàn)這個要求。對于其他的配置選項亦是如此。這對于產品環(huán)境是不能接受的。好在WCF提供針對這個問題的解決方案:配置文件。

    ?

    我們把對服務的配置寫在應用程序的配置文件中(IIS程序是web.config 其他程序是app.config),當配置發(fā)生改變的時候我們就不用重新編譯程序集了。

    ?

    配置文件的寫法很復雜,有很多選項,為了便于上手,我們先從跟本例相關的選項開始。

    ?

    在配置文件中,根節(jié)是<configuration>,所有的配置元素都位于其中。對于WCF服務的配置部分,最外層的節(jié)是<system.serviceModel>,所以配置文件中至少先應該是這個樣子:

    [html] view plaincopyprint?
  • <?xml?version="1.0"?encoding="utf-8"??>??
  • <configuration>??
  • ??<system.serviceModel>??
  • ??????
  • ??</system.serviceModel>??
  • </configuration>??
  • <?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel></system.serviceModel> </configuration>

    現(xiàn)在我們準備開始配置一個服務,服務配置元素標簽為<services></services>,是<system.serviceModel>的子節(jié),在一個宿主上可以承載許多服務,每一個服務用<service></service>來配置,它是<services>的子節(jié)。在配置<service>前,我們還要先添加一個基地址配置,基地址用<baseaddress>描述,他是<host>的子節(jié),<host>是<service>的子節(jié)。

    暈了么...慢慢來。

    先把<services>節(jié)加上,這里可以容納許多服務,注意這個是帶s的

    [html] view plaincopyprint?
  • <?xml?version="1.0"?encoding="utf-8"??>??
  • <configuration>??
  • ??<system.serviceModel>??
  • ????<services>??
  • ????????
  • ????</services>??????
  • ??</system.serviceModel>??
  • </configuration>??
  • <?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><services></services> </system.serviceModel> </configuration>

    在<services>的懷抱中,我們添加一個<service>,這是我們要配置的服務本體,注意這個是不帶s的

    [html] view plaincopyprint?
  • <?xml?version="1.0"?encoding="utf-8"??>??
  • <configuration>??
  • ??<system.serviceModel>??
  • ????<services>??
  • ??????<service>??
  • ??????????
  • ??????</service>??
  • ????</services>??????
  • ??</system.serviceModel>??
  • </configuration>??
  • <?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><services><service></service></services> </system.serviceModel> </configuration>

    在<service>中,添加一個基地址,先添加一個<host>再添加一個<baseaddress>

    [html] view plaincopyprint?
  • <?xml?version="1.0"?encoding="utf-8"??>??
  • <configuration>??
  • ??<system.serviceModel>??
  • ????<services>??
  • ??????<service>??
  • ????????<host>??
  • ??????????<baseAddresses>??
  • ????????????<add?baseAddress="http://localhost:8000/MyService"/>??
  • ??????????</baseAddresses>??
  • ????????</host>??
  • ??????</service>??
  • ????</services>??????
  • ??</system.serviceModel>??
  • </configuration>??
  • <?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><services><service><host><baseAddresses><add baseAddress="http://localhost:8000/MyService"/></baseAddresses></host></service></services> </system.serviceModel> </configuration>

    ?

    到這里,基地址的部分已經完成,對應代碼中的位置你找到了么?

    服務的配置還差一點,我們在代碼中為服務指定了實現(xiàn)類型,在配置文件中如何指定呢?就用<service>標簽的name屬性,指定的時候后要用完全限定名(帶著命名空間)

    [html] view plaincopyprint?
  • <?xml?version="1.0"?encoding="utf-8"??>??
  • <configuration>??
  • ??<system.serviceModel>??
  • ????<services>??
  • ??????<service?name="HelloWCFService.HelloWCFService">??
  • ????????<host>??
  • ??????????<baseAddresses>??
  • ????????????<add?baseAddress="http://localhost:8000/MyService"/>??
  • ??????????</baseAddresses>??
  • ????????</host>??
  • ??????</service>??
  • ????</services>??????
  • ??</system.serviceModel>??
  • </configuration>??
  • <?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><services><service name="HelloWCFService.HelloWCFService"><host><baseAddresses><add baseAddress="http://localhost:8000/MyService"/></baseAddresses></host></service></services> </system.serviceModel> </configuration>

    我這個例子舉的不好了,命名空間和實現(xiàn)類型是一個名字,要注意區(qū)分。

    ?

    到這里,服務也配置完了,對應代碼的位置翻上去找一下。

    接下來配置終結點,終結點用<endpoint>元素表示,正如代碼實現(xiàn)中的參數(shù),在配置中也需要一一指定地址、綁定和服務協(xié)定接口,分別用address、binding和contract屬性來表示,當然<endpoint>也是<service>的子節(jié),畢竟他是屬于服務的嘛。

    [html] view plaincopyprint?
  • <?xml?version="1.0"?encoding="utf-8"??>??
  • <configuration>??
  • ??<system.serviceModel>??
  • ????<services>??
  • ??????<service?name="HelloWCFService.HelloWCFService">??
  • ????????<host>??
  • ??????????<baseAddresses>??
  • ????????????<add?baseAddress="http://localhost:8000/MyService"/>??
  • ??????????</baseAddresses>??
  • ????????</host>??
  • ????????<endpoint?address="HelloWCFService"?binding="wsHttpBinding"?contract="HelloWCFService.IHelloWCFService"?/>??
  • ??????</service>??
  • ????</services>??????
  • ??</system.serviceModel>??
  • </configuration>??
  • <?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><services><service name="HelloWCFService.HelloWCFService"><host><baseAddresses><add baseAddress="http://localhost:8000/MyService"/></baseAddresses></host><endpoint address="HelloWCFService" binding="wsHttpBinding" contract="HelloWCFService.IHelloWCFService" /></service></services> </system.serviceModel> </configuration>

    這里用了相對地址"HelloWCFService",他會和基地址組合在一起(排在后面)成為終結點的地址,這里也可以指定為空字符串"",此時基地址(即服務地址)就是終結點的地址,還可以指定一個絕對地址,那樣他會覆蓋基地址,基地址對這個終結點來說就不起作用了,這里可以看出,終結點的地址是獨立的,可以是基地址的子地址,也可以獨立使用另一個地址,他們之間沒有必然的鏈接。

    這里的contract 同<service>里面一樣,也要使用完全限定名稱(帶上命名空間)。

    注意,在使用IIS承載的時候,必須使用相對地址,也就是終結點必須是基地址的子地址,這是由IIS的部署結構決定的。

    ?

    到這里終結點也配置完成,對應代碼的位置找到了嗎?

    ?

    接下來是最后一步(或者說兩步),配置元數(shù)據(jù)交換終結點并開啟元數(shù)據(jù)交換行為。這個過程,代碼中用了三行,實際上代碼這三行僅僅是添加了元數(shù)據(jù)交換行為,并沒有配置元數(shù)據(jù)交換終結點,運行時系統(tǒng)為我們自動添加了終結點。這兩點缺一不可,雖然系統(tǒng)會為我們添加,我們還是要知道這個配置的寫法。這個很重要。

    ?

    開啟元數(shù)據(jù)交換從原理上應該是兩件事,第一是服務允許元數(shù)據(jù)交換,第二是服務提供元數(shù)據(jù)交換方式,第一條就是添加元數(shù)據(jù)交換行為,表示服務允許這樣的請求,第二條就是服務告訴你如何請求,客戶端是通過一個固定的終結點去請求的,這個終結點的地址、綁定和協(xié)定都是固定的,我們不能更改,這個是框架的約定,我們只能按要求配置。

    ?

    首先,第一條,允許元數(shù)據(jù)交換,這個是通過為服務添加一個行為來實現(xiàn)的,行為是用來描述服務的特性的,不同的服務可能有相同的行為,行為并不是歸某服務獨有的,因此行為被定義為<system.serviceModel>節(jié)的子節(jié),可以被不同的服務引用,他的定義有些像服務,外面是帶s的,里面是不帶s的,畢竟可能有許多的行為定義嘛。

    先定義個行為:

    [html] view plaincopyprint?
  • <?xml?version="1.0"?encoding="utf-8"??>??
  • <configuration>??
  • ??<system.serviceModel>??
  • ????<services>??
  • ??????<service?name="HelloWCFService.HelloWCFService">??
  • ????????<host>??
  • ??????????<baseAddresses>??
  • ????????????<add?baseAddress="http://localhost:8000/MyService"/>??
  • ??????????</baseAddresses>??
  • ????????</host>??
  • ????????<endpoint?address="HelloWCFService"?binding="wsHttpBinding"?contract="HelloWCFService.IHelloWCFService"?/>??
  • ??????</service>??
  • ????</services>??
  • ????<behaviors>??
  • ??????<serviceBehaviors>??
  • ????????<behavior?name="metaExchange">??
  • ??????????<serviceMetadata?httpGetEnabled="true"/>??
  • ????????</behavior>??
  • ??????</serviceBehaviors>??
  • ????</behaviors>??
  • ??</system.serviceModel>??
  • </configuration>??
  • <?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><services><service name="HelloWCFService.HelloWCFService"><host><baseAddresses><add baseAddress="http://localhost:8000/MyService"/></baseAddresses></host><endpoint address="HelloWCFService" binding="wsHttpBinding" contract="HelloWCFService.IHelloWCFService" /></service></services><behaviors><serviceBehaviors><behavior name="metaExchange"><serviceMetadata httpGetEnabled="true"/></behavior></serviceBehaviors></behaviors></system.serviceModel> </configuration>

    因為存在服務行為和終結點行為之分,所有<behaviors>和<behavior>之間又套了一個<serviceBehaviors>,表示這個是服務行為,我們?yōu)樾袨橹贫嗣?#xff0c;好讓<service>可以引用,也可以不指定,那么所有服務都會應用。交換元數(shù)據(jù)的行為有固定的標簽描述,就是<serviceMetadata>,對著代碼看,很熟悉吧。

    ?

    建立了行為以后,要讓我們剛才建立的服務去引用他,用<service>的behaviorConfiguration屬性:

    [html] view plaincopyprint?
  • <?xml?version="1.0"?encoding="utf-8"??>??
  • <configuration>??
  • ??<system.serviceModel>??
  • ????<services>??
  • ??????<service?name="HelloWCFService.HelloWCFService"behaviorConfiguration="metaExchange">??
  • ????????<host>??
  • ??????????<baseAddresses>??
  • ????????????<add?baseAddress="http://localhost:8000/MyService"/>??
  • ??????????</baseAddresses>??
  • ????????</host>??
  • ????????<endpoint?address="HelloWCFService"?binding="wsHttpBinding"?contract="HelloWCFService.IHelloWCFService"?/>??
  • ??????</service>??
  • ????</services>??
  • ????<behaviors>??
  • ??????<serviceBehaviors>??
  • ????????<behavior?name="metaExchange">??
  • ??????????<serviceMetadata?httpGetEnabled="true"/>??
  • ????????</behavior>??
  • ??????</serviceBehaviors>??
  • ????</behaviors>??
  • ??</system.serviceModel>??
  • </configuration>??
  • <?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><services><service name="HelloWCFService.HelloWCFService"behaviorConfiguration="metaExchange"><host><baseAddresses><add baseAddress="http://localhost:8000/MyService"/></baseAddresses></host><endpoint address="HelloWCFService" binding="wsHttpBinding" contract="HelloWCFService.IHelloWCFService" /></service></services><behaviors><serviceBehaviors><behavior name="metaExchange"><serviceMetadata httpGetEnabled="true"/></behavior></serviceBehaviors></behaviors></system.serviceModel> </configuration>

    ?

    接下來第二步,建立元數(shù)據(jù)交換終結點,建立的位置和我們剛才建立的終結點位置相同,但是屬性是固定的,大小寫都不能寫錯。

    [html] view plaincopyprint?
  • <?xml?version="1.0"?encoding="utf-8"??>??
  • <configuration>??
  • ??<system.serviceModel>??
  • ????<services>??
  • ??????<service?name="HelloWCFService.HelloWCFService"?behaviorConfiguration="metaExchange">??
  • ????????<host>??
  • ??????????<baseAddresses>??
  • ????????????<add?baseAddress="http://localhost:8000/MyService"/>??
  • ??????????</baseAddresses>??
  • ????????</host>??
  • ????????<endpoint?address="HelloWCFService"?binding="wsHttpBinding"?contract="HelloWCFService.IHelloWCFService"?/>??
  • ????????<endpoint?address="mex"?binding="mexHttpBinding"?contract="IMetadataExchange"/>??
  • ??????</service>??
  • ????</services>??
  • ????<behaviors>??
  • ??????<serviceBehaviors>??
  • ????????<behavior?name="metaExchange">??
  • ??????????<serviceMetadata?httpGetEnabled="true"/>??
  • ????????</behavior>??
  • ??????</serviceBehaviors>??
  • ????</behaviors>??
  • ??</system.serviceModel>??
  • </configuration>??
  • <?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><services><service name="HelloWCFService.HelloWCFService" behaviorConfiguration="metaExchange"><host><baseAddresses><add baseAddress="http://localhost:8000/MyService"/></baseAddresses></host><endpoint address="HelloWCFService" binding="wsHttpBinding" contract="HelloWCFService.IHelloWCFService" /><endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/></service></services><behaviors><serviceBehaviors><behavior name="metaExchange"><serviceMetadata httpGetEnabled="true"/></behavior></serviceBehaviors></behaviors></system.serviceModel> </configuration>

    到這里,配置文件就寫完了。我們把它放到程序里面去,打開上一篇中建立的服務端程序,為程序添加一個配置文件

    右鍵點擊項目->添加->新建項->應用程序配置文件,名字系統(tǒng)會起好(app.config)。把上面的配置寫進去,保存。

    既然我們已經有了配置文件,就不需要(也不應該)在代碼中配置了。代碼中的配置會覆蓋掉配置文件中的配置。所以我們要對代碼修改一下。

    main函數(shù)中只留下這么幾行:

    [csharp] view plaincopyprint?
  • ServiceHost?host?=?new?ServiceHost(typeof(HelloWCFService));??
  • ??
  • host.Open();??
  • ??
  • Console.WriteLine("Service?is?Ready");??
  • Console.WriteLine("Press?Any?Key?to?Terminate...");??
  • Console.ReadLine();??
  • ??
  • host.Close();??
  • ServiceHost host = new ServiceHost(typeof(HelloWCFService));host.Open();Console.WriteLine("Service is Ready");Console.WriteLine("Press Any Key to Terminate...");Console.ReadLine();host.Close();

    其中,建立SeviceHost 那行被修改了,去掉了baseAddress的參數(shù),但是我們仍需要告訴host 我們要寄存的服務類的類型。

    F5運行起來。

    然后在瀏覽器中訪問一下服務試試

    [html] view plaincopyprint?
  • http://localhost:8000/MyService??
  • http://localhost:8000/MyService

    是不是和昨天的結果一樣呢。

    (CSDN的傳圖好象掛了哩...)

    ?

    總結一下今天的學習。

    我們使用配置文件的方法完成了對WCF服務的配置,從中接觸到了服務、終結點和行為的配置方法。配置文件的元素還有許多,像綁定、安全性等等特性。在今后學到的時候再慢慢展開,配置文件的每一個元素都應該力求背著寫下來,一行一行的寫,在寫的過程中體會,而不是四處復制和粘貼,這樣才能對配置文件的寫法有深刻的印象。

    ?

    相關資源

    徐長龍老師播講的《跟我一起從零開始學WCF系列課程》

    http://msdn.microsoft.com/zh-cn/hh148206

    ?

    MSDN技術資源庫中的WCF參考

    http://msdn.microsoft.com/zh-cn/library/dd456779.aspx

    總結

    以上是生活随笔為你收集整理的[老老实实学WCF] 第二篇 配置WCF的全部內容,希望文章能夠幫你解決所遇到的問題。

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