WCF常见问题(3) -- WCF 4.0 Simple Configuration 如何修改默认Binding

WCF 4.0 引入了一些新的特性,其中 Simple Configuration 大大简化了 WCF 的配置:结合 Service Markup 和默认Binding,WCF 开发者们只要更专心于逻辑的实现。先来看看 VS2010 下创建一个 WCF Service Application 后生成的配置文件:

WCF常见问题(3) -- WCF 4.0 Simple Configuration 如何修改默认Binding

【.NET 4.0 生成的配置文件】

(只贴出来 ServiceModel 配置节的内容)

<system.serviceModel> <behaviors> <serviceBehaviors> <behavior> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel>

【.NET 3.5 生成的配置文件】

(只贴出来 ServiceModel 配置节的内容)

<system.serviceModel> <services> <service name="WcfService35.Service1" behaviorConfiguration="WcfService35.Service1Behavior"> <!-- Service Endpoints --> <endpoint address="" binding="wsHttpBinding" contract="WcfService35.IService1"> <!-- Upon deployment, the following identity element should be removed or replaced to reflect the identity under which the deployed service runs. If removed, WCF will infer an appropriate identity automatically. --> <identity> <dns value="localhost"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="WcfService35.Service1Behavior"> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>通过比较可以发现 WCF 4.0 里去掉了 services 配置节,默认使用的是 BasicHttpBinding,整个配置简洁了很多。

但问题就来了,当需要使用 BasicHttpBinding 以外的 Binding 时该如何配置呢?下面提供几种方案来解决这个问题。

【方案1】 通过 WCF Config tool 添加 services 配置节,即还像 .net 3.5 一样把完整的 service 配置出来

:WCF常见问题(3) -- WCF 4.0 Simple Configuration 如何修改默认BindingWCF常见问题(3) -- WCF 4.0 Simple Configuration 如何修改默认Binding
然后在 Services 里添加 Service Endpoint ,注意:在 WCF Service Application 时,Address 不需要指定。

WCF常见问题(3) -- WCF 4.0 Simple Configuration 如何修改默认Binding

这样配置文件就修改OK了:

<system.serviceModel> <services> <service name="WcfSimpleConfigServiceApplication.Service1"> <endpoint address="" binding="wsHttpBinding" bindingConfiguration="" contract="WcfSimpleConfigServiceApplication.IService1" /> </service> </services> <behaviors> <serviceBehaviors> <behavior> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel>【方案2】利用 WCF 4.0里新增的protocolMapping 配置节

这是最简单的解决方案,直接在system.serviceModel 配置节中加入:

<protocolMapping>
<add binding="wsHttpBinding" scheme="http"/>
</protocolMapping>

通过协议-绑定的方式,WCF4.0框架自动选择 Binding。

【方案3】使用编程方式,添加Binding

首先来看看 Service1.svc 的 Markup:
<%@ ServiceHost Language="C#" Debug="true" Service="WcfSimpleConfigServiceApplication.Service1" CodeBehind="Service1.svc.cs" %>

在 WCF Services Application 这种工程模板里,是不需要你手动编码实现 Host 的,因为它使用的是 IIS Host,WCF框架通过上面的 Markup 默认使用ServiceHostFactory 来加载 Service。当然ServiceHostFactory 使用的是默认的 BasicHttpBinding。编程模式修改 Binding 就需要我们自己实现一个 HostFactory,添加不同的 Binding。(下面代码需要添加System.ServiceModel.Activation.dll

public class WsHttpBindingServiceHostFactory : ServiceHostFactory { protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) { ServiceHost host = new ServiceHost(serviceType, baseAddresses); host.AddServiceEndpoint(typeof(IService1), new WSHttpBinding(), ""); return host; } } 然后在 Markup 里指明这个自定义的 HostFactory:

<%@ ServiceHost Language="C#" Debug="true" Factory="WcfSimpleConfigServiceApplication.WsHttpBindingServiceHostFactory" Service="WcfSimpleConfigServiceApplication.Service1" CodeBehind="Service1.svc.cs" %>

另外,不在 Markup 里指定,也可以通过 web.config 里配置实现,二者选其一:

<serviceHostingEnvironment multipleSiteBindingsEnabled="true"> <serviceActivations> <add service="WcfSimpleConfigServiceApplication.Service1" factory="WcfSimpleConfigServiceApplication.WsHttpBindingServiceHostFactory" relativeAddress="Service1.svc"/> </serviceActivations> </serviceHostingEnvironment>
总的来说,第一种回归完全配置,不仅仅是Binding,自定义Binding行为时也需要要。第二种最简单快速。第三种方式,编程方式实现,
主要是在Factory上做文章。