在协定和服务中指定和处理错误Specifying and Handling Faults in Contracts and Services

Windows Communication Foundation (WCF)应用程序通过将托管异常对象映射到 SOAP 错误对象,将 SOAP 错误对象映射到托管异常对象来处理错误情况。Windows Communication Foundation (WCF) applications handle error situations by mapping managed exception objects to SOAP fault objects and SOAP fault objects to managed exception objects. 本节中的主题讨论如何设计协定以将错误条件作为自定义 SOAP 错误公开、如何作为服务实现的一部分返回这些错误,以及客户端如何捕捉这些错误。The topics in this section discuss how to design contracts to expose error conditions as custom SOAP faults, how to return such faults as part of service implementation, and how clients catch such faults.

错误处理概述Error Handling Overview

在所有托管应用程序中,处理错误由 Exception 对象表示。In all managed applications, processing errors are represented by Exception objects. 在基于 SOAP 的应用程序(例如 WCF 应用程序)中,服务方法使用 SOAP 错误消息来传递处理错误信息。In SOAP-based applications such as WCF applications, service methods communicate processing error information using SOAP fault messages. SOAP 错误是包括在服务操作元数据中的消息类型,因此会创建一个错误协定,客户端可使用该协定来使操作更加可靠或更具交互性。SOAP faults are message types that are included in the metadata for a service operation and therefore create a fault contract that clients can use to make their operation more robust or interactive. 此外,因为 SOAP 错误是以 XML 形式表示的客户端,所以它是高度可互操作的类型系统,可供任何 SOAP 平台上的客户端使用,从而提高 WCF 应用程序的范围。In addition, because SOAP faults are expressed to clients in XML form, it is a highly interoperable type system that clients on any SOAP platform can use, increasing the reach of your WCF application.

因为 WCF 应用程序以这两种类型的错误系统运行,所以,发送到客户端的任何托管异常信息都必须从异常转换为服务上的 SOAP 错误,发送,并从 SOAP 错误转换为 WCF 客户端中的错误异常。Because WCF applications run under both types of error systems, any managed exception information that is sent to the client must be converted from exceptions into SOAP faults on the service, sent, and converted from SOAP faults to fault exceptions in WCF clients. 对于双工客户端,客户端协定还可以将 SOAP 错误发送回服务。In the case of duplex clients, client contracts can also send SOAP faults back to a service. 在任一种情况下,您都可以使用默认的服务异常行为,或者可以显式控制是否(以及如何)将异常映射到错误消息。In either case, you can use the default service exception behaviors, or you can explicitly control whether—and how—exceptions are mapped to fault messages.

可以发送两种类型的 SOAP 错误:已声明并未声明Two types of SOAP faults can be sent: declared and undeclared. 已声明的 SOAP 错误是指其中的某个操作具有 System.ServiceModel.FaultContractAttribute 属性(用于指定自定义 SOAP 错误类型)的错误。Declared SOAP faults are those in which an operation has a System.ServiceModel.FaultContractAttribute attribute that specifies a custom SOAP fault type. 声明未在操作的协定中指定 SOAP 错误。Undeclared SOAP faults are not specified in the contract for an operation.

强烈建议服务操作使用 FaultContractAttribute 属性来声明其错误,以正式指定在正常操作过程中客户端应该可以接收的所有 SOAP 错误。It is strongly recommended that service operations declare their faults by using the FaultContractAttribute attribute to formally specify all SOAP faults that a client can expect to receive in the normal course of an operation. 此外,还建议在 SOAP 错误中仅返回客户端必须了解的信息,以将信息泄露的风险降至最低。It is also recommended that you return in a SOAP fault only the information that a client must know to minimize information disclosure.

通常,服务(以及双工客户端)使用下列步骤将错误处理成功地集成到其应用程序中:Typically, services (and duplex clients) take the following steps to successfully integrate error handling into their applications:

  • 将异常条件映射到自定义 SOAP 错误。Map exception conditions to custom SOAP faults.

  • 客户端和服务将 SOAP 错误作为异常进行发送和接收。Clients and services send and receive SOAP faults as exceptions.

此外,WCF 客户端和服务可以出于调试目的使用未声明的 soap 错误,并且可以扩展默认的错误行为。In addition, WCF clients and services can use undeclared soap faults for debugging purposes and can extend the default error behavior. 下面的部分讨论这些任务和概念。The following sections discuss these tasks and concepts.

将异常映射到 SOAP 错误Map Exceptions to SOAP Faults

创建用于处理错误条件的操作的第一步是:决定在什么条件下应向客户端应用程序通知有关错误的信息。The first step in creating an operation that handles error conditions is to decide under what conditions a client application should be informed about errors. 某些操作具有特定于其功能的错误条件。Some operations have error conditions specific to their functionality. 例如,PurchaseOrder 操作可能会向不再允许其发起采购订单的用户返回特定信息。For example, a PurchaseOrder operation might return specific information to customers who are no longer permitted to initiate a purchase order. 在其他情况下(如 Calculator 服务),一个更宽泛的 MathFault SOAP 错误也许可以描述整个服务内的所有错误条件。In other cases, such as a Calculator service, a more general MathFault SOAP fault may be able to describe all error conditions across an entire service. 在标识服务客户端的错误条件之后,可以构造一个自定义 SOAP 错误,并可以将操作标记为在出现相应的 SOAP 错误条件时返回该 SOAP 错误。Once the error conditions of clients of your service are identified, a custom SOAP fault can be constructed and the operation can be marked as returning that SOAP fault when its corresponding error condition arises.

有关开发服务或客户端的这一步的详细信息,请参阅定义和指定错误For more information about this step of developing your service or client, see Defining and Specifying Faults.

客户端和服务将 SOAP 错误作为异常进行处理Clients and Services Handle SOAP Faults as Exceptions

WCF 应用程序中成功的错误处理的第一步是确定操作错误条件,定义自定义 SOAP 错误,并将这些操作标记为返回这些错误。Identifying operation error conditions, defining custom SOAP faults, and marking those operations as returning those faults are the first steps in successful error handling in WCF applications. 下一步是正确实现这些错误的发送和接收。The next step is to properly implement the sending and receiving of these faults. 通常,服务会发送错误以通知客户端应用程序有关错误条件的情况,但是双工客户端也可以向服务发送 SOAP 错误。Typically services send faults to inform client applications about error conditions, but duplex clients can also send SOAP faults to services.

有关详细信息,请参阅发送和接收错误For more information, see Sending and Receiving Faults.

未声明的 SOAP 错误和调试Undeclared SOAP Faults and Debugging

已声明的 SOAP 错误对于生成可靠的并可互操作的分布式应用程序非常有用。Declared SOAP faults are extremely useful for building robust, interoperable, distributed applications. 但在某些情况下,服务(或双工客户端)发送未声明的 SOAP 错误(即在相应操作的 Web 服务描述语言 (WSDL) 中未提及的错误)也很有用。However, in some cases it is useful for a service (or duplex client) to send an undeclared SOAP fault, one that is not mentioned in the Web Services Description Language (WSDL) for that operation. 例如,在开发服务时可能会出现意外情况,此时就可以将相关信息发送回客户端以方便调试。For example, when developing a service, unexpected situations can occur in which it is useful for debugging purposes to send information back to the client. 此外,还可以将 ServiceBehaviorAttribute.IncludeExceptionDetailInFaults 属性或 ServiceDebugBehavior.IncludeExceptionDetailInFaults 属性设置为 true,以允许 WCF 客户端获取有关内部服务操作异常的信息。In addition, you can set the ServiceBehaviorAttribute.IncludeExceptionDetailInFaults property or the ServiceDebugBehavior.IncludeExceptionDetailInFaults property to true to permit WCF clients to obtain information about internal service operation exceptions. 发送和接收错误中描述了发送单个错误和设置调试行为属性。Both sending individual faults and setting the debugging behavior properties are described in Sending and Receiving Faults.

重要

因为托管异常可以公开内部应用程序信息,所以将 ServiceBehaviorAttribute.IncludeExceptionDetailInFaultsServiceDebugBehavior.IncludeExceptionDetailInFaults 设置为 true 可允许 WCF 客户端获取有关内部服务操作异常的信息,包括个人身份或其他敏感信息信息.Because managed exceptions can expose internal application information, setting ServiceBehaviorAttribute.IncludeExceptionDetailInFaults or ServiceDebugBehavior.IncludeExceptionDetailInFaults to true can permit WCF clients to obtain information about internal service operation exceptions, including personally identifiable or other sensitive information.

因此,建议将 ServiceBehaviorAttribute.IncludeExceptionDetailInFaultsServiceDebugBehavior.IncludeExceptionDetailInFaults 设置为 true 仅用作一种临时调试应用程序的方法。Therefore, setting ServiceBehaviorAttribute.IncludeExceptionDetailInFaults or ServiceDebugBehavior.IncludeExceptionDetailInFaults to true is recommended only as a way to temporarily debug a service application. 此外,以这种方式返回未处理的托管异常的方法的 WSDL 并不包含类型为 FaultException<TDetail>ExceptionDetail 的协定。In addition, the WSDL for a method that returns unhandled managed exceptions in this way does not contain the contract for the FaultException<TDetail> of type ExceptionDetail. 客户端必须预期发生未知 SOAP 错误(返回给 WCF 客户端作为 System.ServiceModel.FaultException 对象)才能正确获取调试信息。Clients must expect the possibility of an unknown SOAP fault (returned to WCF clients as System.ServiceModel.FaultException objects) to obtain the debugging information properly.

使用 IErrorHandler 自定义错误处理Customizing Error Handling with IErrorHandler

如果对于自定义在发生应用程序级别的异常时发送给客户端的响应消息有特殊要求,或者对于在返回响应消息之后执行某些自定义处理有特殊的要求,请实现 System.ServiceModel.Dispatcher.IErrorHandler 接口。If you have special requirements to either customize the response message to the client when an application-level exception happens or perform some custom processing after the response message is returned, implement the System.ServiceModel.Dispatcher.IErrorHandler interface.

错误的序列化问题Fault Serialization Issues

在反序列化错误协定时,WCF 首先尝试将 SOAP 消息中的错误协定名称与错误协定类型相匹配。When deserializing a fault contract, WCF first attempts to match the fault contract name in the SOAP message with the fault contract type. 如果找不到精确匹配项,它将按字母顺序在可用错误协定列表中搜索兼容类型。If it cannot find an exact match it will then search the list of available fault contracts in alphabetical order for a compatible type. 如果两个错误协定是兼容类型(例如,一个是另一个的子类),则可能会使用错误类型对错误进行反序列化。If two fault contracts are compatible types (one is a subclass of another, for example) the wrong type may be used to de-serialize the fault. 仅当错误协定未指定名称、命名空间和操作时,才会发生此状况。This only occurs if the fault contract does not specify a name, namespace, and action. 若要防止此问题发生,则通过指定名称、命名空间和操作特性来始终完全限定错误协定。To prevent this issue from occurring, always fully qualify fault contracts by specifying the name, namespace, and action attributes. 此外,如果您定义了许多派生自共享基类的相关错误协定,请确保使用 [DataMember(IsRequired=true)] 标记所有新成员。Additionally if you have defined a number of related fault contracts derived from a shared base class, make sure to mark any new members with [DataMember(IsRequired=true)]. 有关此 IsRequired 特性的更多信息,请参见 DataMemberAttributeFor more information on this IsRequired attribute see, DataMemberAttribute. 这将防止基类成为兼容类型,并强制将错误反序列化为正确的派生类型。This will prevent a base class from being a compatible type and force the fault to be deserialized into the correct derived type.

请参阅See also