通过纯代码方式发布WCF服务
Posted HOT SUMMER
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过纯代码方式发布WCF服务相关的知识,希望对你有一定的参考价值。
网络上搜索WCF服务,一般是寄宿在IIS,通过WebConfig方式配服务地址,接口类型等信息,但是对于我这样的懒人,目前项目在开发阶段,实在不愿意每次添加新服务就更新配置文件,于是使用了反射来加载服务接口,并用控制台程序发布服务,贴上代码如下。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Description; using System.ServiceModel.Configuration; using Nebula.Proxy; using System.Reflection; using System.Configuration; using System.Xml; namespace MES_WCFService { public class HostIniter { public HostIniter() { } private ServiceHostCollection hosts; private Type[] interfaceTypes; private Type[] implTypes; private string addressBase; private string tcpPort; private string httpPort; private string basehttpPort; /// <summary> /// 通过反射获取所有服务接口及其实现类 /// </summary> private void ScanService() { interfaceTypes = Assembly.Load(ConfigurationManager.AppSettings["interfaceDLLName"]).GetTypes(); implTypes = Assembly.Load(ConfigurationManager.AppSettings["implDLLName"]).GetTypes(); } public ServiceHostCollection InitHost() { hosts = new ServiceHostCollection(); addressBase = ConfigurationManager.AppSettings["baseAddress"]; tcpPort = ConfigurationManager.AppSettings["tcpPort"]; httpPort = ConfigurationManager.AppSettings["httpPort"]; basehttpPort = ConfigurationManager.AppSettings["basehttpPort"]; ScanService(); foreach (Type implType in implTypes) { try { if (!typeof(IWCFService).IsAssignableFrom(implType)) { continue; } string baseNameSpace= "http://" + addressBase + ":" + httpPort + "/WCFService/"; string address = baseNameSpace + implType.Name; Uri baseAddress = new Uri(address); ServiceHost host = new ServiceHost(implType, baseAddress); // Console.WriteLine("Add:" + implType.FullName); Console.WriteLine("Address:" + address); host.Description.Namespace = baseNameSpace; host.Description.Name = implType.Name; ServiceSecurityAuditBehavior secBehacior = new ServiceSecurityAuditBehavior(); secBehacior.MessageAuthenticationAuditLevel = AuditLevel.None; secBehacior.ServiceAuthorizationAuditLevel = AuditLevel.None; host.Description.Behaviors.Add(secBehacior); // secBehacior. ServiceMetadataBehavior metaBehavior = new ServiceMetadataBehavior(); metaBehavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15; metaBehavior.HttpGetEnabled = true; ServiceDebugBehavior debugBehavior = host.Description.Behaviors[typeof(ServiceDebugBehavior)] as ServiceDebugBehavior; debugBehavior.IncludeExceptionDetailInFaults = true; host.Description.Behaviors.Add(metaBehavior); Type t = host.GetType(); object obj = t.Assembly.CreateInstance("System.ServiceModel.Dispatcher.DataContractSerializerServiceBehavior", true, BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { false, Int32.MaxValue }, null, null); IServiceBehavior myServiceBehavior = obj as IServiceBehavior; if (myServiceBehavior != null) { host.Description.Behaviors.Add(myServiceBehavior); // Console.WriteLine("Add DataContractSerializerServiceBehavior !"); } ////host.Description.Behaviors.Add(debugBehavior); foreach (Type interfaceType in interfaceTypes) { if (interfaceType == typeof(IWCFService)) { continue; } if (interfaceType.IsAssignableFrom(implType)) { //本来是WSHttpBinding 为了让Java能调用到这些服务,遂改BasicHttpBinding BasicHttpBinding wsBinding = new BasicHttpBinding(); wsBinding.Security.Mode =BasicHttpSecurityMode.None; wsBinding.MaxBufferPoolSize = 524288; wsBinding.MaxReceivedMessageSize = int.MaxValue; wsBinding.ReaderQuotas.MaxStringContentLength = 0xfffffff; wsBinding.ReaderQuotas.MaxArrayLength = 0xfffffff; wsBinding.ReaderQuotas.MaxBytesPerRead = 0xfffffff; wsBinding.ReaderQuotas.MaxDepth = 0xfffffff; wsBinding.MessageEncoding = WSMessageEncoding.Text; wsBinding.TextEncoding = Encoding.UTF8; wsBinding.OpenTimeout = new TimeSpan(0, 30, 0); wsBinding.ReceiveTimeout = new TimeSpan(0, 30, 0); wsBinding.SendTimeout = new TimeSpan(0, 30, 0); ContractDescription contractDescription = ContractDescription.GetContract(interfaceType); ServiceEndpoint httpEndpoint = new ServiceEndpoint(contractDescription, wsBinding, new EndpointAddress(baseAddress)); httpEndpoint.Name = "http" + implType.Name; host.Description.Endpoints.Add(httpEndpoint); NetTcpBinding netTcpBinding = new NetTcpBinding() { Security = new NetTcpSecurity { Mode = SecurityMode.None } }; netTcpBinding.Security.Mode = SecurityMode.None; netTcpBinding.MaxBufferPoolSize = 524288; netTcpBinding.MaxReceivedMessageSize = int.MaxValue; netTcpBinding.ReaderQuotas.MaxStringContentLength = 0xfffffff; netTcpBinding.ReaderQuotas.MaxArrayLength = 0xfffffff; netTcpBinding.ReaderQuotas.MaxBytesPerRead = 0xfffffff; netTcpBinding.ReaderQuotas.MaxDepth = 0xfffffff; netTcpBinding.OpenTimeout = new TimeSpan(0, 30, 0); netTcpBinding.ReceiveTimeout = new TimeSpan(0, 30, 0); netTcpBinding.SendTimeout = new TimeSpan(0, 30, 0); ServiceEndpoint tcpEndpoint = new ServiceEndpoint(contractDescription, netTcpBinding, new EndpointAddress("net.tcp://" + addressBase + ":" + tcpPort + "/WCFService/" + implType.Name)); tcpEndpoint.Name = "tcp" + implType.Name; host.Description.Endpoints.Add(tcpEndpoint); host.AddServiceEndpoint( ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex" ); break; } } //添加自定义的 Behavior host.Description.Behaviors.Add(new MesServiceInterceptorAttribute()); hosts.Add(host); } catch (Exception commProblem) { Console.WriteLine("There was a problem with this type ;"+implType.FullName); Console.WriteLine("Message:" + commProblem.Message); Console.WriteLine("StackTrace:" + commProblem.StackTrace); Console.Read(); } } return hosts; } } } MesServiceInterceptorAttribute的代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel.Description; using System.ServiceModel; using System.Collections.ObjectModel; using System.ServiceModel.Channels; namespace MES_WCFService { [AttributeUsage(AttributeTargets.Class)] public class MesServiceInterceptorAttribute : Attribute, IServiceBehavior { protected MesOperationInterceptorAttribute CreateOperationInterceptor() { return new MesOperationInterceptorAttribute(); } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase host) { foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints) { foreach (OperationDescription operation in endpoint.Contract.Operations) { bool checkresult = false; foreach (IOperationBehavior behavior in operation.Behaviors) { if (behavior is MesOperationInterceptorAttribute) { checkresult = true; break; } } if (!checkresult) { operation.Behaviors.Add(CreateOperationInterceptor()); } } } } public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } } } MesOperationInterceptorAttribute的: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel.Description; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; namespace MES_WCFService { [AttributeUsage(AttributeTargets.Method)] public class MesOperationInterceptorAttribute : Attribute, IOperationBehavior { //private InterceptionType m_InteType = InterceptionType.None; private string _operatName; public MesOperationInterceptorAttribute() { } //public MesOperationInterceptorAttribute(InterceptionType inteType) //{ // this.m_InteType = inteType; //} protected MesInvoker CreateInvoker(IOperationInvoker oldInvoker) { return new MesInvoker(oldInvoker, _operatName); } public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { } public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) { IOperationInvoker oldInvoker = dispatchOperation.Invoker; _operatName = dispatchOperation.Name; dispatchOperation.Invoker = CreateInvoker(oldInvoker); } public void Validate(OperationDescription operationDescription) { } } }
以上是关于通过纯代码方式发布WCF服务的主要内容,如果未能解决你的问题,请参考以下文章
通过C#代码调用WCF服务中的一个方法。不依赖配置文件等。求完整代码!!