你的位置:首页 > ASP.net教程

[ASP.net教程]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的调用。