自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解自定義托管宿主WCF解決方案開發(fā)配置過程

開發(fā) 開發(fā)工具
考慮到WCF分布式開發(fā)項(xiàng)目中關(guān)于托管宿主服務(wù)配置和客戶端添加引用。兩個(gè)環(huán)節(jié)最容易出錯(cuò)。對(duì)于大部分想學(xué)習(xí)WCF分布式開發(fā)的人來說,成功開發(fā)、配置、部署第一個(gè)自己的WCF服務(wù)困難重重。本文將給大家一些指引。

本節(jié)基本結(jié)構(gòu)是:首先介紹1WCF服務(wù)解決方案的項(xiàng)目組成2WCF服務(wù)的開發(fā)和配置過程,3自定義宿主的開發(fā)和配置過程4客戶端的服務(wù)引用和配置過程??偨Y(jié)算是為各位WCF分布式技術(shù)開發(fā)的愛好者,提供的一個(gè)開發(fā)參考。

一 WCF服務(wù)解決方案的項(xiàng)目組成

WCF服務(wù):

通常來說,WCF服務(wù)由三個(gè)部分構(gòu)成:

服務(wù)類:包含服務(wù)契約、操作契約和數(shù)據(jù)契約的定義和實(shí)現(xiàn);

宿主:一種應(yīng)用程序域和進(jìn)程,服務(wù)將在該環(huán)境中運(yùn)行;

終結(jié)點(diǎn):由客戶端用于訪問服務(wù)。

我們這里的解決方案包括服務(wù)類項(xiàng)目、托管宿主、和簡(jiǎn)單的客戶端程序,結(jié)構(gòu)如圖:

 

客戶端應(yīng)用程序:

上一節(jié)我們介紹了WCF的基本概念,WCF基本通信機(jī)制是基于SOAP消息,SOAP消息基于XML語言,因此WCF應(yīng)用程序可與運(yùn)行于各種上下文環(huán)境的其他進(jìn)程進(jìn)行通信,當(dāng)然也支持跨系統(tǒng)、跨平臺(tái)的應(yīng)用程序之間的數(shù)據(jù)交互。基于WCF構(gòu)建的分布式應(yīng)用程序可與下列所有程序進(jìn)行交互:

同一Windows計(jì)算機(jī)上不同進(jìn)程中的WCF應(yīng)用程序。

另一Windows計(jì)算機(jī)上的WCF應(yīng)用程序。

基于其他技術(shù)構(gòu)建的應(yīng)用程序,如基于Java2企業(yè)版(J2EE)構(gòu)建的、支持標(biāo)準(zhǔn)Web服務(wù)的應(yīng)用程序服務(wù)器。這些應(yīng)用程序可以運(yùn)行在Windows計(jì)算機(jī)上,也可以運(yùn)行在其他操作系統(tǒng)(如SunSolaris、IBM的z/OS或Linux)上。

因此可以作為客戶端的應(yīng)用程序,并不限制其類型,只要可以解析基于XML的SOAP消息,都可以與WCF的服務(wù)端進(jìn)行通信。.NET平臺(tái)上我們可以創(chuàng)建控制臺(tái)應(yīng)用程序、WinForm、Windows服務(wù)、ASP.NET應(yīng)用程序等,來訪問和調(diào)用WCF服務(wù)。下面我們就來具體介紹自定義托管服務(wù),WCF解決方案的開發(fā)配置的詳細(xì)過程。

二 WCF服務(wù)類的開發(fā)過程:

要?jiǎng)?chuàng)建WCF服務(wù)解決方案,首先應(yīng)該定義服務(wù)類,并編寫服務(wù)類的相關(guān)的代碼。我們這里把服務(wù)類創(chuàng)建類單獨(dú)的類庫項(xiàng)目,托管宿主程序項(xiàng)目引用服務(wù)類的程序集。

創(chuàng)建WCF服務(wù)類庫項(xiàng)目:

WCF服務(wù)類庫項(xiàng)目的創(chuàng)建非常簡(jiǎn)單,VisualStudio2008為我們提供了便捷的方式,選擇新建項(xiàng)目,選擇--WCF服務(wù)類庫項(xiàng)目項(xiàng)目,輸入項(xiàng)目名稱,選擇保存位置就可以。如圖:

 

當(dāng)然我們也可以建立空項(xiàng)目,但是程序集引用等操作要手動(dòng)完整,過程相對(duì)復(fù)雜。這里我們選擇的使用創(chuàng)建向?qū)Х绞健?/P>

System.ServiceModel和System.Runtime.Serialization程序集對(duì)WCF服務(wù)至關(guān)重要,因?yàn)楹罄m(xù)服務(wù)契約、操作契約和數(shù)據(jù)契約等特性定義都在這兩個(gè)程序集中。我們?cè)谛陆ǖ捻?xiàng)目引用中可以看到:

 

使用WCF契約相關(guān)的屬性,必須顯示引用這兩個(gè)命名空間.語句如下:

usingSystem.ServiceModel;
usingSystem.Runtime.Serialization;

如果不添加命名空間引用程序集,編寫的代碼會(huì)出現(xiàn)錯(cuò)誤,無法通過。

服務(wù)契約和操作契約:

WCF服務(wù)類庫創(chuàng)建完畢后,我們可以來進(jìn)行代碼的實(shí)際編寫。我們知道,每個(gè)WCF服務(wù)類均需實(shí)現(xiàn)一些方法,以供其客戶端使用。服務(wù)類的創(chuàng)建者通過將這些方法包含在某個(gè)服務(wù)契約中,來決定將哪些方法公開為客戶可調(diào)用的操作。服務(wù)契約就是顯示指定的服務(wù)必須實(shí)現(xiàn)的用戶可以使用的操作。

ServiceContract屬性以及WCF使用的所有其他屬性均在System.ServiceModel命名空間中定義,類聲明使用using語句來引用該命名空間。服務(wù)類中可被客戶端調(diào)用的每個(gè)方法都必須使用名為OperationContract的另一個(gè)屬性加以標(biāo)記。服務(wù)類中帶有前置OperationContract屬性的所有方法都將自動(dòng)被WCF公開為SOAP可調(diào)用操作。

WCF中最基本的屬性是ServiceContract。實(shí)際上,WCF服務(wù)類本身就是標(biāo)記有ServiceContract屬性的類或者是實(shí)現(xiàn)了標(biāo)記有該屬性的接口的類。我們使用的還是上次的代碼:

首先是服務(wù)契約IWCFService,定義了連個(gè)操作,添加[OperationContract]屬性標(biāo)記:

//1.服務(wù)契約
[ServiceContract(Namespace="publicinterfaceIWCFService
{
//操作契約
[OperationContract]
stringSayHello(stringname);
//操作契約
[OperationContract]
stringSayHelloToUser(Useruser);}

其次定義WCF服務(wù)類,繼承服務(wù)契約,實(shí)現(xiàn)服務(wù)契約中聲明的操作,具體代碼如下:

//2.服務(wù)類,繼承接口。實(shí)現(xiàn)服務(wù)契約定義的操作
publicclassWCFService:IWCFService
{
//實(shí)現(xiàn)接口定義的方法
publicstringSayHello(stringname)
{
Console.WriteLine("Hello!{0},Usingstring",name);
return"Hello!"+name;
}
//實(shí)現(xiàn)接口定義的方法
publicstringSayHelloToUser(Useruser)
{
Console.WriteLine("Hello!{0}{1},UsingDataContract",user.FirstName,user.LastName);
return"Hello!"+user.FirstName+""+user.LastName;
}
}


服務(wù)類里給出了服務(wù)契約里聲明的方法,也就是操作,這里都給出了具體的實(shí)現(xiàn)。SayHello()和SayHelloToUser(Useruser)方法都將自動(dòng)被WCF公開為SOAP可調(diào)用操作。客戶端可以調(diào)用相應(yīng)的操作。

數(shù)據(jù)契約:

數(shù)據(jù)契約定義類型如何轉(zhuǎn)換為適合標(biāo)準(zhǔn)信息格式,即“序列化”過程。實(shí)際上,數(shù)據(jù)契約是控制數(shù)據(jù)如何序列化的一種機(jī)制。在WCF服務(wù)類中,數(shù)據(jù)契約使用DataContract屬性來定義。標(biāo)記有DataContract的數(shù)據(jù)類、結(jié)構(gòu)或其他類型都可以擁有一個(gè)或多個(gè)帶有前置DataMember屬性的成員,指示該成員必須被包含在此類型的序列化值中。不顯示指定的成員不被包含在序列化數(shù)據(jù)中。這里我們定義的數(shù)據(jù)類,包含三個(gè)成員,代碼如下:

//3.數(shù)據(jù)契約//序列化為XML,作為元數(shù)據(jù)封裝到服務(wù)里
[DataContract]
publicstructUser
{
[DataMember]
publicstringFirstName;

publicstringMiddleName;//不會(huì)被傳遞
[DataMember]
publicstringLastName;
}

由于是類庫項(xiàng)目,所以主要涉及的內(nèi)容是契約的定義和服務(wù)類的實(shí)現(xiàn)過程。配置的關(guān)鍵部分也是契約屬性的標(biāo)記。

不涉及配置文件的使用和定制,如果是應(yīng)用程序,需要配置對(duì)應(yīng)的Config文件。

#p#

三 自定義宿主的開發(fā)和配置過程:

我們這里使用的控制臺(tái)程序?yàn)橥泄芩拗?,我們這里講解托管宿主的代碼編寫和配置文件的設(shè)置過程。

托管宿主程序的創(chuàng)建:

使用VS2008新建控制臺(tái)應(yīng)用程序,非常簡(jiǎn)單,選擇新建項(xiàng)目-控制臺(tái)程序,即可。

 托管宿主代碼編寫

這里要添加對(duì)WCF服務(wù)類庫項(xiàng)目的引用,另外要引用ServiceModel程序集。ServiceHost類位于ServiceModel命名空間下。這里比較重要的步驟就是,定義一個(gè)ServiceHost實(shí)例,定義地址,定義終結(jié)點(diǎn)使用ABC地址、契約、綁定。

代碼如下:

//反射方式創(chuàng)建服務(wù)實(shí)例,
//Using方式生命實(shí)例,可以在對(duì)象生命周期結(jié)束時(shí)候,釋放非托管資源
using(ServiceHosthost=newServiceHost(typeof(WCFService.WCFService)))
{
//相同的服務(wù)注冊(cè)多個(gè)基地址
//添加服務(wù)和URI,用戶資源標(biāo)識(shí)符
UritcpAddress=newUri("net.tcp://localhost:8001/WCFService");
UrihttpAddress=newUri("http://localhost:8002/WCFService");
UripipeAddress=newUri("net.pipe://localhost:8002/WCFService");
host.AddServiceEndpoint(typeof(WCFService.IWCFService),newNetTcpBinding(),tcpAddress);
host.AddServiceEndpoint(typeof(WCFService.IWCFService),newWSHttpBinding(),httpAddress);
host.AddServiceEndpoint(typeof(WCFService.IWCFService),newNetNamedPipeBinding(),pipeAddress);
//判斷是否以及打開連接,如果尚未打開,就打開偵聽端口
if(host.State!=CommunicationState.Opening)
host.Open();
//顯示運(yùn)行狀態(tài)
Console.WriteLine("Hostisruning!andstateis{0}",host.State);
//等待輸入即停止服務(wù)
Console.Read();}

值得注意的是定義終結(jié)點(diǎn)的代碼可以由配置文件的定制來實(shí)現(xiàn)。if(host.State!=CommunicationState.Opening)語句是為了判斷是否以及打開連接,如果尚未打開,host.Open();就打開偵聽端口。
Console.Read()語句是阻塞進(jìn)程,使得宿主程序可以一直運(yùn)行下去。直到用戶輸入數(shù)據(jù)。

配置文件的定制

要使WCF宿主程序能夠正確運(yùn)行,還需要編輯配置文件信息。所有的WCF服務(wù)相關(guān)的配置信息都處于app.config文件的節(jié)點(diǎn)內(nèi)。下面我們就來詳細(xì)介紹一下詳細(xì)的配置過程。

服務(wù)結(jié)點(diǎn)配置

指定公布服務(wù)的類型和行為。服務(wù)的行為要在配置文件中給出,我們下面會(huì)給出詳細(xì)的說明。這里的WCF服務(wù)就是我們實(shí)現(xiàn)服務(wù)契約的WCF服務(wù)的類名WCFService。

服務(wù)的終結(jié)點(diǎn)包含ABC,地址、綁定(通信協(xié)議,其實(shí)很拗口)、契約三個(gè)部分。地址包括:通信協(xié)議、機(jī)器地址、端口、服務(wù)名。契約就是服務(wù)契約。我們這里配置了連個(gè)終結(jié)點(diǎn),分別使用HTTP協(xié)議和TCP協(xié)議。端口分別是8001和8002。服務(wù)地址必須不同,所以設(shè)置了兩個(gè)不同的端口。具體的配置代碼如下:

<endpoint
          address="http://localhost:8001/WCFService"
          binding="wsHttpBinding"
          contract="WCFService.IWCFService">
        </endpoint>
<endpoint adress="net.tcp://localhost:8002/WCFService"
          binding="netTcpBinding"
          contract="WCFService.IWCFService">
</endpoint> <ENDPOINTADRESS="NET.TCP: WCFService? localhost:8002></BEHAVIOR>

</SERVICEBEHAVIORS></BEHAVIORS></P>

原數(shù)據(jù)終結(jié)點(diǎn)配置

如果我們希望WCF可以被客戶端查找和引用,我們就要設(shè)置相應(yīng)的元素?fù)?jù)交換節(jié)點(diǎn),來約束WCF服務(wù)的元數(shù)據(jù)交換行為。綁定(通信協(xié)議)和我們上面設(shè)置的服務(wù)終結(jié)點(diǎn)對(duì)應(yīng),這樣客戶端可以以不同的方式獲得元素?fù)?jù),數(shù)據(jù)交換契約為IMetadataExchange,具體代碼如下:

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
這樣客戶端可以通過服務(wù)地址獲得我們公布的WCF服務(wù)的元素?fù)?jù)信息,反序列化創(chuàng)建本地的對(duì)應(yīng)的數(shù)據(jù)類、服務(wù)等類。

行為結(jié)點(diǎn)配置

另外我們可以在這里配置服務(wù)的行文,在配置文件里的<serviceBehaviors>節(jié)點(diǎn)下。定義行為名稱,方便服務(wù)引用。是否可以通過httpGet方式獲取服務(wù)元素?fù)?jù),是否顯示服務(wù)異常的詳細(xì)信息,在這里都可以進(jìn)行設(shè)置。

<behaviors>
      <serviceBehaviors>
        <behavior name="WCFService.WCFServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

這里定義的服務(wù)行為就是在上面被服務(wù)節(jié)點(diǎn)引用的,記住名稱一定要匹配。否則會(huì)出現(xiàn)找不到服務(wù)行為的異常,程序?qū)o法運(yùn)行。以上的方式可以通過編程方式實(shí)現(xiàn),但是相對(duì)來說配置文件使用簡(jiǎn)單,編程方式復(fù)雜,需要代碼,但是功能強(qiáng)大,我們可以編程動(dòng)態(tài)控制服務(wù)運(yùn)行的狀態(tài)。

配置完全后就可以編譯,運(yùn)行托管服務(wù)宿主程序。托管宿主啟動(dòng)正常:

 

四 客戶端的服務(wù)引用、配置和開發(fā)過程

服務(wù)類和服務(wù)宿主已經(jīng)配置完畢,下面我們來講述客戶端添加WCF服務(wù)的引用、配置和服務(wù)調(diào)用過程。

首先要運(yùn)行宿主程序,這樣才能在客戶端添加服務(wù)引用,從元數(shù)據(jù)獲取服務(wù)類的相關(guān)信息,生成本地類。

添加WCF服務(wù)引用

服務(wù)瀏覽器,單擊客戶端項(xiàng)目,添加ServicesReference.在彈出的窗口地址里輸入服務(wù)的基地址,首先查找TCP服務(wù)。

保持地址和配置文件里服務(wù)的基地址相同,:查找成功后的窗口如下:

 

我們可以看到WCF服務(wù)類公布的操作,輸入命名空間的名字為ServiceReferenceTcp。同樣的方式添加對(duì)HTTP服務(wù)的引用。添加成功后我們可以查看所有文件,在客戶端項(xiàng)目的服務(wù)引用的窗口看到所有的服務(wù)引用的文件信息如圖:

 

證明我們添加WCF服務(wù)成功。客戶端app.config文件里會(huì)生成相應(yīng)的服務(wù)代理的相關(guān)信息,包括客戶端終結(jié)點(diǎn)的信息:

<client>
            
<endpoint address="http://localhost:8001/WCFService" binding="wsHttpBinding"
                bindingConfiguration
="WSHttpBinding_IWCFService" 

contract="ServiceReferenceTcp.IWCFService"
                name
="WSHttpBinding_IWCFService">
                
<identity>
                    
<userPrincipalName value="FRANK\Administrator" />
                
</identity>
            
</endpoint>
            
<endpoint address="net.tcp://localhost:8002/WCFService" binding="netTcpBinding"
                bindingConfiguration
="NetTcpBinding_IWCFService" 

contract="ServiceReferenceTcp.IWCFService"
                name
="NetTcpBinding_IWCFService">
                
<identity>
                    
<userPrincipalName value="FRANK\Administrator" />
                
</identity>
            
</endpoint>
            
<endpoint address="http://localhost:8001/WCFService" binding="wsHttpBinding"
                bindingConfiguration
="WSHttpBinding_IWCFService1" 

contract="ServiceReferenceHttp.IWCFService"
                name
="WSHttpBinding_IWCFService1">
                
<identity>
                    
<userPrincipalName value="FRANK\Administrator" />
                
</identity>
            
</endpoint>
            
<endpoint address="net.tcp://localhost:8002/WCFService" binding="netTcpBinding"
                bindingConfiguration
="NetTcpBinding_IWCFService1" 

contract="ServiceReferenceHttp.IWCFService"
                name
="NetTcpBinding_IWCFService1">
                
<identity>
                    
<userPrincipalName value="FRANK\Administrator" />
                
</identity>
            
</endpoint>
        
</client>





客戶端的配置方式和宿主托管方式非常類似,同樣包括地址、綁定、契約等信息。

調(diào)用服務(wù):

要調(diào)用相應(yīng)的服務(wù),需要實(shí)例化服務(wù)代理類的實(shí)例,首先添加命名空間的引用usingServiceReferenceHttp;
usingServiceReferenceTcp;這樣可以使用本地反序列化生成的類和其他配置的信息。我們分別實(shí)例化HTTP和TCP代理的類,非別調(diào)用服務(wù)的不同操作,USER的實(shí)例也分別為不同的命名空間中的類型,需要分別指定命名空間。

具體測(cè)試代碼如下: 

//HTTPWSHttpBinding_IWCFService1
ServiceReferenceHttp.WCFServiceClientwcfServiceProxyHttp=newServiceReferenceHttp.WCFServiceClient("WSHttpBinding_IWCFService1");
//通過代理調(diào)用SayHello服務(wù)
Console.WriteLine(wcfServiceProxyHttp.SayHello("FrankXuLeiWSHttpBinding"));
////通過代理調(diào)用調(diào)用SayHelloToUser,傳遞對(duì)象
ServiceReferenceHttp.Useruser=newServiceReferenceHttp.User();
user.FirstName="WSHttpBinding";
user.LastName="Frank";
Console.WriteLine(wcfServiceProxyHttp.SayHelloToUser(user));

//TCPNetTcpBinding_IWCFService
ServiceReferenceTcp.WCFServiceClientwcfServiceProxyTcp=newServiceReferenceTcp.WCFServiceClient("NetTcpBinding_IWCFService");
//通過代理調(diào)用SayHello服務(wù)
Console.WriteLine(wcfServiceProxyTcp.SayHello("FrankXuLeiNetTcpBinding"));
////通過代理調(diào)用調(diào)用SayHelloToUser,傳遞對(duì)象
ServiceReferenceTcp.UseruserTcp=newServiceReferenceTcp.User();
userTcp.FirstName="NetTcpBinding";
userTcp.LastName="Frank";
Console.WriteLine(wcfServiceProxyTcp.SayHelloToUser(userTcp));

運(yùn)行結(jié)果如圖:

兩者不同的協(xié)議服務(wù)調(diào)用都成功執(zhí)行,并且返回正確的結(jié)果。

總結(jié):

以上就是本節(jié)關(guān)于自定義托管宿主WCF服務(wù)解決方案開發(fā)與配置的詳細(xì)過程,包括服務(wù)代碼的編寫、宿主程序的開發(fā)與配置、客戶端服務(wù)的引用和調(diào)用。我們這里托管宿主服務(wù)使用了配置文件,來配置WCF服務(wù)的信息,這里也可以編碼實(shí)現(xiàn)。

另外客戶端要想通過原數(shù)據(jù)交換來反序列換生成本地的WCF服務(wù)類等相關(guān)代碼,就需要在托管宿主里配置可以使用的原數(shù)據(jù)交換節(jié)點(diǎn),這里缺少設(shè)置,就會(huì)出現(xiàn)獲取服務(wù)元數(shù)據(jù)的異常,導(dǎo)致客戶端添加服務(wù)出錯(cuò)。(最近論文答辯有點(diǎn)忙,所以這個(gè)文章更新的比較慢,不好意思)另外給出本文的參考代碼:/Files/frank_xl/WCFServiceConfigFrankXuLei.rar

希望本篇文章能給大家WCF分布式開發(fā)項(xiàng)目的配置帶來一些幫助。~

【編輯推薦】

  1. WCF開發(fā)基礎(chǔ)
  2. 詳解WCF可擴(kuò)展框架中的行為擴(kuò)展
  3. WCF中通過Dispose有效實(shí)現(xiàn)重用
責(zé)任編輯:彭凡 來源: 博客園
相關(guān)推薦

2009-12-21 17:05:59

WCF自托管宿主

2010-02-23 14:56:18

WCF Bug

2009-11-06 15:41:25

WCF自托管宿主

2010-02-24 09:28:37

WCF安全配置

2010-02-25 11:23:29

WCF返回自定義格式

2010-02-22 10:29:11

WCF上傳文件

2010-03-02 18:12:39

WCF單調(diào)服務(wù)

2011-08-02 11:17:13

iOS開發(fā) View

2010-02-24 14:05:08

WCF openati

2011-07-04 14:08:02

C++

2010-02-24 17:17:04

WCF宿主環(huán)境

2010-02-26 15:46:48

Silverlight

2009-11-06 15:25:25

WCF異常

2009-12-07 15:50:27

WCF文件

2009-11-09 16:06:53

WCF自定義集合

2011-04-19 10:33:16

ASP.NET自定義控

2013-05-20 17:33:44

Android游戲開發(fā)自定義View

2009-12-08 15:19:58

WCF大數(shù)據(jù)量

2012-02-29 09:14:45

ibmdw

2012-03-06 09:19:56

ibmdw
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)