WCF服务编程学习笔记之服务契约

1:服务契约的操作符重载

 

诸如C++和C#等编程语言都支持方法重载,但是,基于WSDL的操作不支持操作重载,如果在WCF中定义重载函数,在启动服务时就会抛出异常InvalidOperationException,异常信息如下:“同一个协定中不能存在两个名称相同的操作,类型为 ServiceContractSample.IServiceContracOverload 的方法 Add 和 Add 违反了此规则。可以通过更改方法名称或使用 OperationContractAttribute 的 Name 属性更改其中一个操作的名称。”

但是WCF可以手动启用操作符重载,实现的方式就是在OperationContract特性的Name特性,为操作指定别名。代码如下:

 

   服务端重载接口的定义:

   [ServiceContract]

    public interface IServiceContracOverload

    {

        [OperationContract(Name="AddInt")]//给此操作契约特性定义名称为AddInt

        int Add(int x, int y);

 

        [OperationContract(Name="AddDouble")]//给此操作契约特性定义名称为AddDouble

        double Add(double x, double y);

}

 

  客户端生成引用后代码:

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="OverloadServiceReference.IServiceContracOverload")]

    public interface IServiceContracOverload {

       

        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IServiceContracOverload/AddInt", ReplyAction="http://tempuri.org/IServiceContracOverload/AddIntResponse")]

        int AddInt(int x, int y);

       

        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IServiceContracOverload/AddDouble", ReplyAction="http://tempuri.org/IServiceContracOverload/AddDoubleResponse")]

        double AddDouble(double x, double y);

}

 

2:服务契约的继承

 

服务端契约接口支持继承功能,但是要在每个层次的接口上都要加上[ServiceContract]的特性标记,这样一个单独的服务类就可以实现所有契约层次的接口功能。对外提供公开一个单独的终结点。

但时,有一点,在生成客户端代理类的时候,客户端契约将不在维持原来的层次关系,它会取消所有的层次,放在单独的一个客户端契约类中。在这个契约类中,包含了从上至下所有的接口定义。

如果使用了OperationContract特性中的Action和ReplyAction这两个属性,它会表明此功能是在服务端是属于哪个接口的。

实例:

服务端定义接口如下:

    [ServiceContract]

    public interface IServiceContractInherited : IServiceContractParent

    {

        [OperationContract]

        void DoWork();

    }

 

    [ServiceContract]

    public interface IServiceContractParent

    {

        [OperationContract]

        void ParentMethod();

}

实现类如下:

    public class ServiceContractInherited : IServiceContractInherited

    {

        #region IServiceContractInherited 成员

        public void DoWork()

        {

            Trace.WriteLine("working...");

          

        }

        public void ParentMethod()

        {

            Trace.WriteLine("ParentMethod working ...");

        }

 

        #endregion

 }

 

在客户端生成的代理类如下:

     [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="InheritedServiceReference.IServiceContractInherited")]

    public interface IServiceContractInherited {

       

        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IServiceContractParent/ParentMethod", ReplyAction="http://tempuri.org/IServiceContractParent/ParentMethodResponse")]

        void ParentMethod();

       

        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IServiceContractInherited/DoWork", ReplyAction="http://tempuri.org/IServiceContractInherited/DoWorkResponse")]

        void DoWork();

}

在客户端的Action和ReplyAction这两属性中,标明了ParentMethod()是属于IServiceContractParent接口内的函数,DoWork()是属于IServiceContractInherited接口内的函数。

   如果想保持契约的层次级别,需要自己修改客户端代理类。

 

3:服务契约的实现类不支持继承多个契约

    在服务契约的服务实现类中,如果继承两个或多个接口,这种情况是不支持的,在生成客户端代理类时,生成的客户端契约只是公开的终结点指定的服务契约接口内的功能。

   实例如下:

   两个服务契约接口:

    [ServiceContract]

    public interface IServiceMultiplyInherited

    {

        [OperationContract]

        void DoWork();

    }

 

    [ServiceContract]

    public interface ISeviceInherited2

    {

        [OperationContract]

        void Test();

}

    服务契约的实现类:

    public class ServiceMultiplyInherited : IServiceMultiplyInherited, ISeviceInherited2

    {

        #region IServiceContractParent 成员

        public void DoWork()

        {

            Trace.WriteLine("working...");

        }

        public void Test()

        {

            Trace.WriteLine("Testing...");

        }

        #endregion

}

 

服务的配置

              <service behaviorConfiguration="ServiceContractSample.ServiceMultiplyInheritedBehavior"

                name="ServiceContractSample.ServiceMultiplyInherited">

                <endpoint address="" binding="wsHttpBinding" contract="ServiceContractSample.ISeviceInherited2">

                    <identity>

                        <dns value="localhost" />

                    </identity>

                </endpoint>

                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

                <host>

                    <baseAddresses>

                        <add baseAddress="http://localhost:8731/ServiceContractSample/ServiceMultiplyInherited/" />

                    </baseAddresses>

                </host>

            </service>

    在生成的客户端代理类中,生成的客户端契约中只包含ISeviceInherited2接口内的功能。

    代码如下:

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] [System.ServiceModel.ServiceContractAttribute(ConfigurationName="MultiplyServiceReference.ISeviceInherited2")]

    public interface ISeviceInherited2 {

    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ISeviceInherited2/Test", ReplyAction="http://tempuri.org/ISeviceInherited2/TestResponse")]

        void Test();

    }

原文地址:https://www.cnblogs.com/jiewei915/p/1764524.html