WCF Part 6 : Address
让我们再次回到WCF ABC,这一部分中,我们重点讲述服务的地址(address)。为服务指定地址,有多种方法,尤其是多种方法的交叉使用。但是本文只关注三个最重要的方法。此外,不要为本文的篇幅吓到,其实本文理解起来是非常容易地.
显式指定方式
在第三部分中,我们讲到过配置相关的内容,也曾在服务的endpoints中的地址属性中显式地配置过服务的地址,一个是服务本身的地址,另外一个是元数据(metadata)的地址。但是我们没有为WSDL寻址设置任何endpoint。如果我们想启用http discovery,就必须设置在serviceMetadata行为中进行设置。因为我们并不是使用相对地址,而是想显示设置它。
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080/Hello/" />
</behavior>
</serviceBehaviors>
通过上面的设置,我们就能马上通过在服务的根地址后面加上/?wsdl来访问wsdl了。
相对方式(Relative)
基于某些原因,一般情况下,建议使用相对地址的方式。其中一个原因就在于方便管理,相对地址可以避免在配置文件和应用程序中的所有地址变得松散不易管理。在许多用户的强烈要求下,为了支持相对地址,WCF设计团队为配置引入了基地址(base addresses)的概念。使用base address,就能变得像下面这样简单。
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="Hello">
<endpoint
address="Hello"
binding="basicHttpBinding"
contract="IHello" />
<endpoint address="MEX" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
如上所示,host节点下面添加了一个base address。下篇文章中,我们将介绍其他的绑定方式,以及如何使用多个base addresses。这样设置,服务的endpoint,MEX endpoint以及WSDL文档(通过httpGetEnabled启用)就都不需要地址了。他们的地址分别如下所示:
- http://localhost:8080/Hello/
- http://localhost:8080/MEX/
- http://localhost:8080/?wsdl
编程方式指定(Programmatically)
在引入base address之前,这种方法就是过去最常用的指定地址的方式。在创建一个ServiceHost对象时,可以指定base addresses。当然也可以使用硬编码的方式,但是实际上我们都不会使用这种方式,因为只要改变了地址,就需要重编译以及重部署。因此我们就从其他的配置文件中读取这个信息,下面就是可能使用的一种配置文件:
<appSettings>
<add key="httpBindingAddress" value="http://localhost:8080/" />
</appSettings>
这样,我们就能将其传递给ServiceHost的构造函数如下所示:
Type type = typeof(Hello);
string httpBindingAddress = ConfigurationManager.AppSettings["httpBindingAddress"];
Uri[] baseAddresses = new Uri[] { new Uri(httpBindingAddress) };
using (ServiceHost host = new ServiceHost(type, baseAddresses))
{
host.Open();
}
多个base addresses(Multiple base addresses)
这里我们暂且不讨论有关绑定和多地址的东西,我们这里重点还是集中在讨论地址上,因此这里只是演示一下多个地址是如何实现的,具体的细节以后再讲。首先,我们使用编程实现的方式。当然,配置文件的不同键就保存着这些不同的地址。示例代码如下:
string httpBindingAddress = ConfigurationManager.AppSettings["httpBindingAddress"];
string nettcpBindingAddress = ConfigurationManager.AppSettings["nettcpBindingAddress"];
Uri httpUri = new Uri(httpBindingAddress);
Uri nettcpUri = new Uri(nettcpBindingAddress);
Uri[] baseAddresses = new Uri[] { httpUri, nettcpUri };
using (ServiceHost host = new ServiceHost(type, baseAddresses))
{
多个地址的使用,也能通过配置文件实现。在相对地址方法中,代码不需要做任何更改。对比一下下面的配置文件和上面一节中相应的配置文件实现,你就会发现奇妙之处了。需要注意的是,MEX endpoint同时拥有http和net-tcp endpoints的信息。
<service behaviorConfiguration="MyServiceBehavior" name="Hello">
<endpoint
address="httpHello"
binding="basicHttpBinding"
contract="IHello" />
<endpoint
address="nettcpHello"
binding="netTcpBinding"
contract="IHello" />
<endpoint address="MEX" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/"/>
<add baseAddress="net.tcp://localhost:8090/"/>
</baseAddresses>
</host>
</service>
注:要查看原始文章,请看这里的全部索引。