WCF 4.0 如何编程修改wcf配置,不使用web.config静态配置

How to programmatically modify WCF without web.config setting

WCF 4.0 如何编程修改wcf配置,不使用web.config静态配置

 

接上一篇

WCF4.0安装 NET.TCP启用及常见问题

的例子,继续

 

在IIS中要实现定义的ServiceHost,需要以下步骤:

1)引入Dll:  System.ServiceModel.Activation

2) 修改 svc文件的头部:

<%@ ServiceHost Language="C#" Debug="true" Service="WcfServiceOfMyTest.Service_Test_NetTcp"
     Factory="CustomServiceHost.SelfDescribingServiceHostFactory"
 CodeBehind="Service1.svc.cs" %>

加入 Factory,每一个svc文件的头部都要做修改,都需要添加。

 

3)实现自己的ServiceHost:

我参考了微软的例子,融入了自己修改:

代码:

SelfDescribingServiceHostFactory.cs

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;


namespace CustomServiceHost
{
    public class SelfDescribingServiceHostFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            //All the custom factory does is return a new instance
            //of our custom host class. The bulk of the custom logic should
            //live in the custom host (as opposed to the factory) for maximum
            //reuse value.
            var host = new SelfDescribingServiceHost(serviceType, baseAddresses);
            return host;

        }

       
    }
}

 

通常,如果我们使用自定义的ServiceHost,最后一句话基本上都是 host.Open(),而在IIS中,我们直接继承 ServiceHostFactory,实现CreateServiceHost函数,并Return host,而不是 直接Open。

 

 

SelfDescribingServiceHost.cs

using System;
using System.Net.Security;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Xml;
using WcfServiceOfMyTest;


namespace CustomServiceHost
{
    //This class is a custom derivative of ServiceHost
    //that can automatically enabled metadata generation
    //for any service it hosts.
    class SelfDescribingServiceHost : ServiceHost
    {
        public SelfDescribingServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        {
        }

        

        //Overriding ApplyConfiguration() allows us to 
        //alter the ServiceDescription prior to opening
        //the service host. 
        protected override void ApplyConfiguration()
        {
            //First, we call base.ApplyConfiguration()
            //to read any configuration that was provided for
            //the service we're hosting. After this call,
            //this.ServiceDescription describes the service
            //as it was configured.
            base.ApplyConfiguration();

            //Now that we've populated the ServiceDescription, we can reach into it
            //and do interesting things (in this case, we'll add an instance of
            //ServiceMetadataBehavior if it's not already there.
            ServiceMetadataBehavior smb = this.Description.Behaviors.Find<ServiceMetadataBehavior>();

            if (smb == null)
            {
                smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = false;
                this.Description.Behaviors.Add(smb);
            }
            else
            {
                ////Metadata behavior has already been configured, 
                ////so we don't have any work to do.
                //return;
            }

            ServiceDebugBehavior sdb = this.Description.Behaviors.Find<ServiceDebugBehavior>();
            if (sdb == null)
            {
                sdb = new ServiceDebugBehavior();
                this.Description.Behaviors.Add(sdb);
            }
            sdb.IncludeExceptionDetailInFaults = true;
            
            

            ServiceBehaviorAttribute sba = this.Description.Behaviors.Find<ServiceBehaviorAttribute>();
            if (sba == null)
            {
                sba = new ServiceBehaviorAttribute();

                this.Description.Behaviors.Add(sba);
            }
            sba.IncludeExceptionDetailInFaults = true;
            sba.MaxItemsInObjectGraph = int.MaxValue;
            

            ServiceThrottlingBehavior stb = this.Description.Behaviors.Find<ServiceThrottlingBehavior>();
            if (stb == null)
            {
                stb = new ServiceThrottlingBehavior();
                stb.MaxConcurrentCalls = int.MaxValue;
                //stb.MaxConcurrentSessions = int.MaxValue; 
                this.Description.Behaviors.Add(stb);
            }

            var items = this.Description.Endpoints;

            //这个东西无法在代码中修改,只能在web.config 中修改
            //ServiceHostingEnvironment.MultipleSiteBindingsEnabled = true;

            //Add a metadata endpoint at each base address
            //using the "/mex" addressing convention
            foreach (Uri baseAddress in this.BaseAddresses)
            {
                if (baseAddress.Scheme == Uri.UriSchemeHttp)
                {
                    /*
                     svcutil.exe http: //localhost/WcfServiceOfMyTest/Service1.svc?wsdl
                     */
                    smb.HttpGetEnabled = true;
                    this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                            MetadataExchangeBindings.CreateMexHttpBinding(),
                                            "mex");
                }
                else if (baseAddress.Scheme == Uri.UriSchemeHttps)
                {
                    smb.HttpsGetEnabled = true;
                    this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                            MetadataExchangeBindings.CreateMexHttpsBinding(),
                                            "mex");
                }
                else if (baseAddress.Scheme == Uri.UriSchemeNetPipe)
                {
                    this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                            MetadataExchangeBindings.CreateMexNamedPipeBinding(),
                                            "mex");
                }
                else if (baseAddress.Scheme == Uri.UriSchemeNetTcp)
                {
                    //这里只暴露了NET.TCP的协议
                    var tcpBinding = new NetTcpBinding()
                    {
                        Name = "CacheSrvNetTcpBindConfig",
                        ReaderQuotas = XmlDictionaryReaderQuotas.Max,
                        ListenBacklog = int.MaxValue,
                 
                        MaxBufferPoolSize = long.MaxValue,
                        MaxConnections = int.MaxValue,
                        MaxBufferSize = int.MaxValue,
                        MaxReceivedMessageSize = int.MaxValue,
                        PortSharingEnabled = true,
                        CloseTimeout = TimeSpan.FromMinutes(30),
                        OpenTimeout = TimeSpan.FromMinutes(30),
                        ReceiveTimeout = TimeSpan.FromMinutes(30),
                        SendTimeout = TimeSpan.FromMinutes(30),
                        TransactionFlow = false,
                        TransferMode = TransferMode.Buffered,
                        TransactionProtocol = TransactionProtocol.OleTransactions,
                        HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
                        ReliableSession = new OptionalReliableSession
                        {
                            Enabled = false,
                            Ordered = true,
                            InactivityTimeout = TimeSpan.FromMinutes(1)
                        },
                        Security = new NetTcpSecurity
                        {
                            Mode = SecurityMode.None,
                            Message = new MessageSecurityOverTcp
                            {
                                ClientCredentialType = MessageCredentialType.None
                            },
                            Transport = new TcpTransportSecurity
                            {
                                ClientCredentialType = TcpClientCredentialType.None,
                                ProtectionLevel = ProtectionLevel.None
                            }
                        }
                    };


                    /*
                     svcutil.exe net.tcp://dst52382.cn1.global.ctrip.com/WcfServiceOfMyTest/Service1.svc/mex
                     */
                    this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                                   tcpBinding,//MetadataExchangeBindings.CreateMexTcpBinding(),
                                                   "mex");

                    this.AddServiceEndpoint(typeof(IJustAnInterface), tcpBinding, "");
                }
            }

        }
    }



    


}

 

Web.config

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
    <system.serviceModel>
      <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    </system.serviceModel>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2013-12-05 20:55 softfair 阅读(...) 评论(...) 编辑 收藏