了解生成的客户端代码

ServiceModel 元数据实用工具工具(Svcutil.exe)生成用于生成客户端应用程序的客户端代码和客户端应用程序配置文件。 本主题介绍标准服务协定方案生成的代码示例。 有关使用生成的代码生成客户端应用程序的详细信息,请参阅 WCF 客户端概述

概述

如果使用 Visual Studio 为项目生成 Windows Communication Foundation (WCF) 客户端类型,通常不需要检查生成的客户端代码。 如果不使用执行相同服务的开发环境,则可以使用 Svcutil.exe 等工具生成客户端代码,然后使用该代码开发客户端应用程序。

由于 Svcutil.exe 有许多用于修改生成的类型信息的选项,因此本主题不讨论所有方案。 但是,以下标准任务涉及查找生成的代码:

  • 标识服务协定接口。

  • 标识 WCF 客户端类。

  • 标识数据类型。

  • 标识双工服务的回调协定。

  • 标识帮助器服务协定通道接口。

查找服务协定接口

若要查找建模服务合同的接口,请搜索标有 System.ServiceModel.ServiceContractAttribute 属性的接口。 通常,由于存在其他属性和属性本身上设置的显式属性,因此很难通过快速读取找到此属性。 请记住,服务协定接口和客户端协定接口是两种不同类型的。 下面的代码示例显示了原始服务协定。

[ServiceContractAttribute(
  Namespace = "http://microsoft.wcf.documentation"
)]
public interface ISampleService
{
  [OperationContractAttribute]
  [FaultContractAttribute(typeof(microsoft.wcf.documentation.SampleFault))]
  string SampleMethod(string msg);
}

下面的代码示例演示 Svcutil.exe 生成的相同服务协定。

[System.ServiceModel.ServiceContractAttribute(
  Namespace = "http://microsoft.wcf.documentation"
)]
public interface ISampleService
{
    [System.ServiceModel.OperationContractAttribute(
      Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethod",
      ReplyAction = "http://microsoft.wcf.documentation/ISampleService/SampleMethodResponse"
    )]
    [System.ServiceModel.FaultContractAttribute(
      typeof(microsoft.wcf.documentation.SampleFault),
      Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethodSampleFaultFault"
    )]
    string SampleMethod(string msg);
}

可以使用生成的服务协定接口和 System.ServiceModel.ChannelFactory 类来创建一个用于调用服务作的 WCF 通道对象。 有关详细信息,请参阅 如何:使用 ChannelFactory

查找 WCF 客户端类

要查找实现你要使用的服务协定的 WCF 客户端类,请搜索 System.ServiceModel.ClientBase<TChannel> 的扩展名,其中类型参数为先前找到的且扩展该接口的服务协定接口。 下面的代码示例显示了 ClientBase<TChannel> 类型的 ISampleService类。

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class SampleServiceClient : System.ServiceModel.ClientBase<ISampleService>, ISampleService
{

    public SampleServiceClient()
    {
    }

    public SampleServiceClient(string endpointConfigurationName)
        :
            base(endpointConfigurationName)
    {
    }

    public SampleServiceClient(string endpointConfigurationName, string remoteAddress)
        :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public SampleServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress)
        :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public SampleServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress)
        :
            base(binding, remoteAddress)
    {
    }
    public string SampleMethod(string msg)
    {
        return base.Channel.SampleMethod(msg);
    }
}

可以通过创建它的新实例并调用它实现的方法来使用此 WCF 客户端类。 这些方法调用服务操作,可设计和配置该服务操作以进行交互。 有关详细信息,请参阅 WCF 客户端概述

注释

SvcUtil.exe 在生成 WCF 客户端类时会将一个 DebuggerStepThroughAttribute 添加到该客户端类,以防止调试器逐步调试该 WCF 客户端类。

查找数据类型

若要在生成的代码中找到数据类型,最基本的机制是标识协定中指定的类型名称,并搜索该类型声明的代码。 例如,以下协定指定 SampleMethod 可以返回类型的 microsoft.wcf.documentation.SampleFaultSOAP 错误。

[System.ServiceModel.OperationContractAttribute(
  Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethod",
  ReplyAction = "http://microsoft.wcf.documentation/ISampleService/SampleMethodResponse"
)]
[System.ServiceModel.FaultContractAttribute(
  typeof(microsoft.wcf.documentation.SampleFault),
  Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethodSampleFaultFault"
)]
string SampleMethod(string msg);

查找SampleFault会定位以下类型声明。

[assembly: System.Runtime.Serialization.ContractNamespaceAttribute(
  "http://microsoft.wcf.documentation",
  ClrNamespace = "microsoft.wcf.documentation"
)]
namespace microsoft.wcf.documentation
{
    using System.Runtime.Serialization;

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute()]
    public partial class SampleFault : object, System.Runtime.Serialization.IExtensibleDataObject
    {
        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
        private string FaultMessageField;

        public System.Runtime.Serialization.ExtensionDataObject ExtensionData
        {
            get
            {
                return this.extensionDataField;
            }
            set
            {
                this.extensionDataField = value;
            }
        }

        [System.Runtime.Serialization.DataMemberAttribute()]
        public string FaultMessage
        {
            get
            {
                return this.FaultMessageField;
            }
            set
            {
                this.FaultMessageField = value;
            }
        }
    }
}

在这种情况下,数据类型是由客户端上特定异常引发的详细信息类型,其中 FaultException<TDetail> 详细信息类型参数为 microsoft.wcf.documentation.SampleFault。 有关数据类型的详细信息,请参阅 在服务协定中指定数据传输。 有关在客户端中处理异常的详细信息,请参阅 发送和接收错误

查找双工服务的回调协定

如果找到一个服务合同,其中合同接口为属性 ServiceContractAttribute.CallbackContract 指定了一个值,那么该合同就是一个双向合同。 双工协定要求客户端应用程序创建一个回调类,该类实现回调协定并将此类的一个实例传递给 System.ServiceModel.DuplexClientBase<TChannel> 或用来与服务进行通信的 System.ServiceModel.DuplexChannelFactory<TChannel> 。 有关双工客户端的详细信息,请参阅如何:使用双工协定访问服务

以下合同指定类型为 SampleDuplexHelloCallback 的回调合同。

[System.ServiceModel.ServiceContractAttribute(
  Namespace="http://microsoft.wcf.documentation",
  ConfigurationName="SampleDuplexHello",
  CallbackContract=typeof(SampleDuplexHelloCallback),
  SessionMode=System.ServiceModel.SessionMode.Required
)]
public interface SampleDuplexHello
{
  [System.ServiceModel.OperationContractAttribute(
      IsOneWay=true,
      Action="http://microsoft.wcf.documentation/SampleDuplexHello/Hello"
    )]
    void Hello(string greeting);
  }
    <System.ServiceModel.OperationContractAttribute(IsOneWay:=True, _
        Action:="http://microsoft.wcf.documentation/SampleDuplexHello/Hello")> _
    Sub Hello(ByVal greeting As String)
End Interface 'SampleDuplexHello

搜索该回调协定将找到客户端应用程序必须实现的以下接口。

  [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface SampleDuplexHelloCallback
{
  [System.ServiceModel.OperationContractAttribute(
      IsOneWay=true,
      Action="http://microsoft.wcf.documentation/SampleDuplexHello/Reply"
    )]
    void Reply(string responseToGreeting);
  }
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")>  _
Public Interface SampleDuplexHelloCallback
    <System.ServiceModel.OperationContractAttribute( _
        IsOneWay:=True, _
        Action:="http://microsoft.wcf.documentation/SampleDuplexHello/Reply")> _
    Sub Reply(ByVal responseToGreeting As String)
End Interface 'SampleDuplexHelloCallback

查找服务协定通道接口

ChannelFactory 类与服务协定接口一起使用时,您必须强制转换到 System.ServiceModel.IClientChannel 接口以显式打开、关闭或中止通道。 为便于操作,Svcutil.exe 工具还生成一个帮助器接口,该接口可同时实现服务协定接口和 IClientChannel ,以使您无需进行强制转换就能够与客户端通道基础结构进行交互。 以下代码显示了实现上述服务协定的帮助程序客户端通道的定义。

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface ISampleServiceChannel : ISampleService, System.ServiceModel.IClientChannel
{
}

另请参阅