培训
了解生成的客户端代码
ServiceModel Metadata Utility Tool (Svcutil.exe) 可生成用于生成客户端应用程序的客户端代码和客户端应用程序配置文件。 本主题提供了有关标准服务协定方案的生成代码示例的教程。 有关使用生成的代码生成客户端应用程序的详细信息,请参阅 WCF 客户端概述。
如果使用 Visual Studio 来生成项目的 Windows Communication Foundation (WCF) 客户端类型,通常并不需要检查生成的客户端代码。 如果您并未使用为您执行相同服务的开发环境,您可以使用 Svcutil.exe 之类的工具来生成客户端代码,然后使用该代码开发客户端应用程序。
由于 Svcutil.exe 具有许多可以修改生成的类型信息的选项,因此本主题并不对所有方案进行讨论。 但是,以下标准任务涉及查找生成的代码:
标识服务协定接口。
标识 WCF 客户端类。
标识数据类型。
标识双工服务的回调协定。
标识帮助器服务协定通道接口。
若要查找对服务协定建模的接口,请搜索使用 System.ServiceModel.ServiceContractAttribute 属性进行标记的接口。 由于存在其他属性 (Attribute) 和设置在该属性 (Attribute) 自身上的显式属性 (Property),因此要通过快速读取查找该属性 (Attribute) 通常并不容易。 请记住,服务协定接口和客户端协定接口属于两种不同的类型。 下面的代码示例演示原始服务协定。
[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 客户端类,请搜索 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.SampleFault
类型的 SOAP 错误。
[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
{
}