WCF系列(二) -- 使用配置文件构建和使用WCF服务
當(dāng)然,配置一個(gè)ServiceHost除了上面說的完全使用代碼的方式,更好的方式是使用配置文件,把一些可能需要修改的屬性跟代碼分離,放到配置文件中,這樣可以提供服務(wù)配置的靈活性,也更容易維護(hù)。
看看前面那個(gè)不用配置文件的WCF的例子改成使用配置文件會(huì)是怎樣配置的。
1、服務(wù)端
1.1.??? 準(zhǔn)備Contract和實(shí)現(xiàn)Contract的服務(wù)
這部分是功能接口和功能實(shí)現(xiàn)部分,不需要配置,所以這部分跟前面一樣。
[ServiceContract()]
?public interface IService
?{
???? [OperationContract]
???? string MyOperation1(string myValue);
?}
?public class Service : IService
?{
???? public string MyOperation1(string myValue)
???? {
???????? return "Hello: " + myValue;
???? }
}
1.2.??? 建立ServiceHost
前面使用public ServiceHost(Type serviceType, params Uri[] baseAddresses)構(gòu)造方法建立ServicesHost。
這里建立ServiceHost實(shí)例也必須使用代碼,但是可以使用簡(jiǎn)單些的構(gòu)造方法:
ServiceHost myServiceHost = new ServiceHost(typeof(Service))
只要給ServiceHost指定你要運(yùn)行服務(wù)的類型,就是告訴要駐留在ServiceHost里的哪個(gè)WCF服務(wù)(實(shí)現(xiàn)某個(gè)或某些Contract的類)。BaseAddress部分這里不需要指定了,可以放在配置文件里。
編碼部分就這些,剩下的部分都只要通過配置文件進(jìn)行設(shè)置即可。
1.3.??? WCF配置
WCF的配置使用.NET Framework的System.Configuration配置系統(tǒng)。在Visual Studio中配置一個(gè)WCF服務(wù)時(shí),如果宿主是一般的windows應(yīng)用或console應(yīng)用,則配置文件為App.confing,,如果宿主是IIS應(yīng)用,則配置文件為Web.config。
跟WCF相關(guān)的配置主要有三個(gè)元素:
<system.serviceModel>
<system.serviceModel.activation>
<system.runtime.serialization>
這三個(gè)元素都是.NET Framework配置文件的根元素<configuration>下的元素,其中<system.serviceModel>元素最為基本,WCF的基本設(shè)置集中在這個(gè)元素中。
看一下<system.serviceModel>元素的簡(jiǎn)單結(jié)構(gòu):
<configuration>
??? <system.serviceModel>
??????? <!-- services 元素包含應(yīng)用中駐留的所有service的配置要求 -->
??????? <services>
??????? </services>
??????? <!--定義service和Endpiont行為-->
??????? <behaviors>
??????? </behaviors>
??????? <bindings>
??????? </bindings>
??????? <!--定義客戶端的配置-->
??????? <client>
??????? </client>
??? </system.serviceModel>
</configuration>
1.4.??? 建立跟ServiceHost相配的service配置
前面已經(jīng)在代碼中建立了ServiceHost,并指定了這個(gè)ServiceHost中要駐留的服務(wù)類型。
在<services>標(biāo)簽下加一個(gè)<service>標(biāo)簽,注意,service的name屬性應(yīng)該是ServiceHost中駐留那個(gè)服務(wù)的全限定名,即名稱空間加類名,表示這個(gè)service元素下的設(shè)置是針對(duì)這個(gè)服務(wù)的。
<services>
??? <servicename="WCFService.Service">
??????? <host>
??????????? <baseAddresses>
??????????????? <addbaseAddress="http://localhost:8080/WCFService/Service" />
??????????? </baseAddresses>
??????? </host>
??? </service>
</services>
在<service>元素下加<host>元素,這里要增加的是baseAddress,跟使用代碼一樣,baseAddress可以有多個(gè),用add標(biāo)簽增加,但是同樣的通訊協(xié)議只能有一個(gè)baseAddress,比如http的只能有一個(gè),https的只能有一個(gè)。
1.5.??? 給service增加Endpoint
本例中WCF服務(wù)對(duì)外只有一個(gè)Endpoint,在<service>元素下增加<endpoint>元素,Endpoint的三個(gè)基本要素address、binding、contract都是<endpoint>元素屬性,當(dāng)然它還有其他屬性,這里先不提及,只描述完成這個(gè)簡(jiǎn)單實(shí)例相關(guān)的設(shè)置。
address - 指定這個(gè)Endpoint對(duì)外的URI,這個(gè)URI可以是個(gè)絕對(duì)地址,也可以是個(gè)相對(duì)于baseAddress的相對(duì)地址。如果此屬性為空,則這個(gè)Endpoint的地址就是baseAddress。
binding - 指定這個(gè)Endpoint使用的binding,這個(gè)banding可以是系統(tǒng)預(yù)定義的9個(gè)binding之一,比如是basicHttpBinding,也可以是自定義的customBinding。binding決定了通訊的類型、安全、如何編碼、是否基于session、是否基于事務(wù)等等。
contract - 指定這個(gè)Endpoint對(duì)應(yīng)的Contract的全限定名(名稱空間.類型名),這個(gè)Contract應(yīng)該被service元素的name指定的那個(gè)service實(shí)現(xiàn)。
<services>
??? <servicebehaviorConfiguration="NewBehavior"name="WCFService.Service">
??????? <endpointaddress=""binding="basicHttpBinding"contract="WCFService.IService" />
??? </service>
</services>
1.6.??? 設(shè)置允許發(fā)布元數(shù)據(jù)
設(shè)置允許通過WSDL對(duì)外暴露對(duì)服務(wù)的Metadata。
是通過設(shè)置服務(wù)端行為的<serviceBehaviors>標(biāo)簽下增加一個(gè)<behavior>,一個(gè)可以定義<behavior>一組服務(wù)端的行為設(shè)置,可以設(shè)置一個(gè)或多個(gè)系統(tǒng)提供的或定制的表示服務(wù)端行為的元素。
Name屬性,一個(gè)behavior唯一標(biāo)識(shí),<service>元素的behaviorConfiguration屬性指向這個(gè)name,即表示這個(gè)service使用這個(gè)behavior的配置。
<serviceMetadata>標(biāo)簽,指定service元數(shù)據(jù)發(fā)布和相關(guān)信息。
httpGetEnabled 屬性是bool類型的值,表示是否允許通過HTTP的get方法獲取sevice的WSDL元數(shù)據(jù)。
httpGetUrl 屬性,如果httpGetEnabled為true,這個(gè)屬性指示使用哪個(gè)URL地址發(fā)布服務(wù)的WSDL,如果這個(gè)屬性沒有設(shè)置,則使用服務(wù)的HTTP類型的baseAddress后面加上?WSDL。
<behaviors>
??? <serviceBehaviors>
??????? <behaviorname="NewBehavior">
??????????? <serviceMetadatahttpGetEnabled="true"httpGetUrl="http://localhost:8001/" />
??????? </behavior>
??? </serviceBehaviors>
</behaviors>
2、客戶端
2.1.??? 引用service
客戶端要訪問服務(wù)端的服務(wù),首先要知道服務(wù)端的服務(wù)提供了什么方法,就是要知道服務(wù)的Contract。如何取得服務(wù)端的Contract有幾種方法,前一篇文章有講述,這里不再贅述,這里同樣采用最方便的在項(xiàng)目中添加Service reference來引用service。
在vs2005中安裝了WCF的extention后,在項(xiàng)目的References上點(diǎn)擊右鍵,會(huì)多出來一個(gè)“Add Service Reference”的選項(xiàng),這就是用來引用WCF服務(wù)的,引用地址就是服務(wù)端設(shè)置的http的baseAddress。
在這里引用WCF服務(wù),跟使用Svcutil.exe命令一樣,會(huì)在項(xiàng)目中生成同樣的兩個(gè)文件。
2.2.??? 生成客戶端service代理實(shí)例和配置文件
引用服務(wù)后,客戶端生成了配置文件和包含了Contract和本地代理類的cs文件。
引用WCF服務(wù)后,還會(huì)在同時(shí)給每個(gè)Contract不同的Endpoint生成一個(gè)繼承自System.ServiceModel.ClientBase的本地代理類。
客戶端可以直接使用多個(gè)重載的代理類構(gòu)造方法實(shí)例化這些代理類。如果要使用配置文件,有這么幾個(gè)構(gòu)造方法可用:
1、public ServiceClient()
2、public ServiceClient(string endpointConfigurationName)
3、public ServiceClient(string endpointConfigurationName, string remoteAddress)
4、public ServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress)
看一下,引用WCF后生成的配置文件中Client部分的內(nèi)容,這部分包含客戶端跟服務(wù)端連接使用到的Endpoint的配置:
<client>
??? <endpointaddress="http://localhost:8080/WCFService/Service"
??????? binding="basicHttpBinding"bindingConfiguration="BasicHttpBinding_IService"
??????? contract="WCFClient.localhost.IService"name="BasicHttpBinding_IService" />
</client>
實(shí)際上,客戶端代理類是從某個(gè)它對(duì)應(yīng)的那個(gè)Contract繼承的,所以客戶端代理類本身一定是跟某個(gè)Contract相關(guān)的。
如果客戶端配置文件中這個(gè)代理類對(duì)應(yīng)的Contract只有一個(gè)Endpoint配置,那么可以使用第一個(gè)構(gòu)造方法,運(yùn)行時(shí),會(huì)根據(jù)代理類的Contract在配置文件中相應(yīng)的配置。
如果客戶端配置文件這個(gè)代理類對(duì)應(yīng)的Contract有多個(gè)Endpoint配置,可以使用第二個(gè)構(gòu)造方法,通過endpointConfigurationName參數(shù)指定使用哪一個(gè)Endpoint的配置。
對(duì)于本例,只有一個(gè)Contract,引用WCF服務(wù)后也只生成一個(gè)Endpoint配置,使用最簡(jiǎn)單的構(gòu)造方法即可:
localhost.ServiceClient proxy = new localhost.ServiceClient();
string result = proxy.MyOperation1("myFirstWCF");
使用配置文件的例子代碼下載:
http://files.cnblogs.com/chnking/ConfigWCF.rar
總結(jié)
以上是生活随笔為你收集整理的WCF系列(二) -- 使用配置文件构建和使用WCF服务的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WCF开发的几个频骤
- 下一篇: 自行车旅行一天多少公里合适(自行车旅行)