zoukankan      html  css  js  c++  java
  • WCF无.SVC文件服务激活,及不添加服务引用调用WCF

    一,新建WCF服务引用程序

      1,删除.svc文件,全部删除。

      2,新建 IService 类

    namespace TestWcf
    {
        [ServiceContract]
        public interface IService
        {
            [OperationContract]
            string DoWork();
        }
    
    }

      3,实现接口类 Service类

    namespace TestWcf
    {
        public class Service : IService
        {
            public string DoWork()
            {
                return "你妹!";
            }
        }
    }

      4,编写配置文件

      <system.serviceModel>
        <!--添加此节点,否则出现405错误-->
        <bindings>
          <wsHttpBinding>
            <binding name="NoneSecurity"
              maxBufferPoolSize="12000000" maxReceivedMessageSize="12000000" useDefaultWebProxy="false">
              <readerQuotas maxStringContentLength="12000000" maxArrayLength="12000000"/>
              <security mode="None"/>
            </binding>
          </wsHttpBinding>
        </bindings>
      
        <behaviors>
          <serviceBehaviors>
            <behavior name="metadataBehavior">
              <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false -->
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
              <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        
        <protocolMapping>
          <add binding="wsHttpBinding" scheme="http" />
        </protocolMapping>
        
        <services>
          <service name="TestWcf.Service" behaviorConfiguration="metadataBehavior">
            <endpoint address="" binding="wsHttpBinding" contract="TestWcf.IService" bindingConfiguration="NoneSecurity">
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
          </service>
        </services>
    
        <!--无svc文件wcf服务激活-->
        <serviceHostingEnvironment>
          <serviceActivations>
            <add relativeAddress="Service.svc" service="TestWcf.Service"/>
          </serviceActivations>
        </serviceHostingEnvironment>
    
      </system.serviceModel>

      5,注意事项

      以下代码是无.svc,激活WCF服务的关键,WCF4.0的新特性

    从消息交换的角度来说,客户端对IIS/WAS寄宿下服务的调用本质上体现在对.svc这个真实存在的物理文件的访问。如果服务尚未激活,WCF最终根据读取请求的物理文件来激活相应的服务。具体来说,就是获 取用于创建ServiceHost的ServiceHostFactory的类型(如果没有通过<%@ServiceHost%>指令的 Factory进行显式设置,默认使用的ServiceHostFactory的类型为 System.ServiceModel.Activation.ServiceHostFactory)。在正确解析出 ServiceHostFactory类型之后,通过反射创建用于寄宿服务的ServiceHost对象

    如果WCF的服务端能够根据请求正确地创建出基于目标服务的ServiceHost,就能解决服务的激活问题。进一步来说,如果服务端能够维护一个 Service/ServiceHostFactory与请求地址之间的映射关系,我们就可以不再需要.svc文件,因为.svc对于服务激活来说就是起 到了这么一个映射的作用。在最新的WCF中,这么一个映射关系可以在配置文件中进行设置。换言之,如果在配置对这个映射关系进行了相应设置之后,我们将不 再需要为服务定义了.svc文件了。

    在<system.serviceModel>/<serviceHostingEnvironment>配置节下,具有 一个<serviceActivations>子节点。上述的关于Service/ServiceHostFactory与请求地址之间的映 射关系就定义在这个配置节点下。具体来说,<serviceActivations>配置节下的配置元素具有三个基本的属性,其中 service和factory对用着原来定义在.svc文件中<%@ServiceHost>指令的Service和Factory属性, 而relativeAddress则表示服务相对服务寄宿的IIS站点的地址,该地址必须以.svc为后缀。下面一段配置与上面给出的.svc文件具有相 同的作用,有了这段配置,.svc就不再需要了。

       <!--无svc文件wcf服务激活-->
        <serviceHostingEnvironment>
          <serviceActivations>
            <add relativeAddress="Service.svc" service="TestWcf.Service"/>
          </serviceActivations>
        </serviceHostingEnvironment>

    二,不直接引用WCF服务,使用代理类实现对WCF的调用

      1,新建控制台程序,新建客户端代理类,MyClient

    namespace WCFClient
    {
        /// <summary>
        /// 用于调用服务的类  
        /// </summary>
        public class MyClient : ClientBase<IService>, IService
        {
            public MyClient(Binding binding, EndpointAddress edpAddress)
                : base(binding, edpAddress)
            {
    
            }
    
            /// <summary>
            /// 调用服务端函数
            /// </summary>
            /// <returns></returns>
            public string DoWork()
            {
                return base.Channel.DoWork();
            }
    
        }
    }

      2,调用测试

    namespace WCFClient
    {
        class Program
        {
            static EndpointAddress edpHttp = new EndpointAddress("http://10.11.109.7:8001/Service.svc");
            static void Main(string[] args)
            {
                MyClient client = new MyClient(new WSHttpBinding(SecurityMode.None), edpHttp);
                
                Console.WriteLine(client.DoWork());
    
                Console.ReadKey();
            }
        }
    }

      3,运行结果

    这样就可以不需要添加服务引用,而直接纯代码手工实现对WCF的调用。

      

  • 相关阅读:
    TypeScript
    monorepo
    Sass和Less
    浏览器的多进程
    React router的Route应用
    CSS3 之 Media(媒体查询器)
    迷失了自己~
    实现跨域的项目实践
    Python开发入门14天集训营-第二章
    Python开发入门14天集训营-第一章
  • 原文地址:https://www.cnblogs.com/softmax/p/4334940.html
Copyright © 2011-2022 走看看