FaultContractAttribute 类

定义

指定服务操作遇到处理错误时返回的一个或多个 SOAP 错误。

public ref class FaultContractAttribute sealed : Attribute
[System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=true, Inherited=false)]
public sealed class FaultContractAttribute : Attribute
[<System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=true, Inherited=false)>]
type FaultContractAttribute = class
    inherit Attribute
Public NotInheritable Class FaultContractAttribute
Inherits Attribute
继承
FaultContractAttribute
属性

示例

下面的代码示例演示如何使用 FaultContractAttribute 来指定 SampleMethod 操作可以使用详细信息类型 GreetingFault 返回 SOAP 错误。

using System;
using System.Collections.Generic;
using System.Net.Security;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Microsoft.WCF.Documentation
{
  [ServiceContract(Namespace="http://microsoft.wcf.documentation")]
  public interface ISampleService{
    [OperationContract]
    [FaultContractAttribute(
      typeof(GreetingFault),
      Action="http://www.contoso.com/GreetingFault",
      ProtectionLevel=ProtectionLevel.EncryptAndSign
      )]
    string SampleMethod(string msg);
  }

  [DataContractAttribute]
  public class GreetingFault
  {
    private string report;

    public GreetingFault(string message)
    {
      this.report = message;
    }

    [DataMemberAttribute]
    public string Message
    {
      get { return this.report; }
      set { this.report = value; }
    }
  }

  class SampleService : ISampleService
  {
  #region ISampleService Members

  public string  SampleMethod(string msg)
  {
    Console.WriteLine("Client said: " + msg);
    // Generate intermittent error behavior.
    Random rnd = new Random(DateTime.Now.Millisecond);
    int test = rnd.Next(5);
    if (test % 2 != 0)
      return "The service greets you: " + msg;
    else
      throw new FaultException<GreetingFault>(new GreetingFault("A Greeting error occurred. You said: " + msg));
  }

  #endregion
  }
}

Imports System.Collections.Generic
Imports System.Net.Security
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.Text

Namespace Microsoft.WCF.Documentation
  <ServiceContract(Namespace:="http://microsoft.wcf.documentation")> _
  Public Interface ISampleService
    <OperationContract, FaultContractAttribute(GetType(GreetingFault), Action:="http://www.contoso.com/GreetingFault", ProtectionLevel:=ProtectionLevel.EncryptAndSign)> _
    Function SampleMethod(ByVal msg As String) As String
  End Interface

  <DataContractAttribute> _
  Public Class GreetingFault
    Private report As String

    Public Sub New(ByVal message As String)
      Me.report = message
    End Sub

    <DataMemberAttribute> _
    Public Property Message() As String
      Get
          Return Me.report
      End Get
      Set(ByVal value As String)
          Me.report = value
      End Set
    End Property
  End Class

  Friend Class SampleService
      Implements ISampleService
  #Region "ISampleService Members"

  Public Function SampleMethod(ByVal msg As String) As String Implements ISampleService.SampleMethod
    Console.WriteLine("Client said: " & msg)
    ' Generate intermittent error behavior.
    Dim rand As New Random(DateTime.Now.Millisecond)
    Dim test As Integer = rand.Next(5)
    If test Mod 2 <> 0 Then
      Return "The service greets you: " & msg
    Else
      Throw New FaultException(Of GreetingFault)(New GreetingFault("A Greeting error occurred. You said: " & msg))
    End If
  End Function

  #End Region
  End Class
End Namespace

下面的代码示例演示此 SOAP 错误的 WCF 客户端ISampleService的类型FaultException<TDetail>GreetingFault

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WCF.Documentation;

public class Client
{
  public static void Main()
  {
    // Picks up configuration from the config file.
    SampleServiceClient wcfClient = new SampleServiceClient();
    try
    {
      // Making calls.
      Console.WriteLine("Enter the greeting to send: ");
      string greeting = Console.ReadLine();
      Console.WriteLine("The service responded: " + wcfClient.SampleMethod(greeting));

      Console.WriteLine("Press ENTER to exit:");
      Console.ReadLine();

      // Done with service.
      wcfClient.Close();
      Console.WriteLine("Done!");
    }
    catch (TimeoutException timeProblem)
    {
      Console.WriteLine("The service operation timed out. " + timeProblem.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (FaultException<GreetingFault> greetingFault)
    {
      Console.WriteLine(greetingFault.Detail.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (FaultException unknownFault)
    {
      Console.WriteLine("An unknown exception was received. " + unknownFault.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (CommunicationException commProblem)
    {
      Console.WriteLine("There was a communication problem. " + commProblem.Message + commProblem.StackTrace);
      Console.ReadLine();
      wcfClient.Abort();
    }
  }
}

Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports Microsoft.WCF.Documentation

Public Class Client
  Public Shared Sub Main()
    ' Picks up configuration from the config file.
    Dim wcfClient As New SampleServiceClient()
    Try
      ' Making calls.
      Console.WriteLine("Enter the greeting to send: ")
      Dim greeting As String = Console.ReadLine()
      Console.WriteLine("The service responded: " & wcfClient.SampleMethod(greeting))

      Console.WriteLine("Press ENTER to exit:")
      Console.ReadLine()

      ' Done with service. 
      wcfClient.Close()
      Console.WriteLine("Done!")
    Catch timeProblem As TimeoutException
      Console.WriteLine("The service operation timed out. " & timeProblem.Message)
      Console.ReadLine()
      wcfClient.Abort()
    Catch greetingFault As FaultException(Of GreetingFault)
      Console.WriteLine(greetingFault.Detail.Message)
      Console.ReadLine()
      wcfClient.Abort()
    Catch unknownFault As FaultException
      Console.WriteLine("An unknown exception was received. " & unknownFault.Message)
      Console.ReadLine()
      wcfClient.Abort()
    Catch commProblem As CommunicationException
      Console.WriteLine("There was a communication problem. " & commProblem.Message + commProblem.StackTrace)
      Console.ReadLine()
      wcfClient.Abort()
    End Try
  End Sub
End Class

注解

使用 FaultContractAttribute 属性标记一个操作,以声明添加到 Web 服务描述语言的一个或多个特定异常条件, (WSDL) 服务操作的说明作为操作返回的显式 SOAP 错误消息。

在所有托管应用程序中,处理错误由 Exception 对象表示。 在基于 SOAP 的应用程序(如 Windows Communication Foundation (WCF) 应用程序)中,服务方法使用 SOAP 错误消息传达处理错误信息。 由于 WCF 应用程序在两种类型的错误系统下执行,因此必须将必须发送到客户端的任何托管异常信息从异常转换为 SOAP 错误。 您可以使用默认的服务异常行为,或者可以显式控制异常是否能被映射到错误消息,以及如何映射到错误消息。 有关 WCF 应用程序中的异常和 SOAP 错误的概述,请参阅 在协定和服务中指定和处理错误

建议服务操作使用 FaultContractAttribute 该服务操作来正式指定客户端在正常操作过程中可以接收的所有 SOAP 错误。 此外,还建议在 SOAP 错误中仅返回客户端必须了解的信息,以将信息泄露风险降至最低。

  • Action 属性控制错误消息的操作。

  • DetailType 属性获取在错误消息中序列化的详细信息对象的类型。

  • NameNamespace属性分别控制错误消息的名称和命名空间。

  • 指示 HasProtectionLevel 错误消息是否指定了保护级别,如果是,则 ProtectionLevel 属性控制该保护级别。

注意

如果错误消息包含敏感信息或可能导致安全问题的信息,强烈建议 ProtectionLevel 设置该属性。

对于许多方案,对于EncryptAndSign错误消息的设置ProtectionLevel就足够了。 有关详细信息,请参阅 了解保护级别

若要从标记 FaultContractAttribute的操作返回指定的错误,请引发一个 FaultException<TDetail> (,其中类型参数是操作期间发生托管异常时) 可序列化的错误信息。 WCF 客户端应用程序将 SOAP 错误呈现为与客户端实现中引发的类型相同的类型-即,作为 FaultException<TDetail> 类型参数是可序列化的错误信息) (。 FaultContractAttribute只能用于为双向服务操作和异步操作对指定 SOAP 错误;单向操作不支持 SOAP 错误,因此不支持 FaultContractAttributeSOAP 错误。

备注

您可以使用任意可序列化的类型来传达错误信息。 The only restriction in this version of WCF is that types specified in a FaultContractAttribute must be serializable by the System.Runtime.Serialization.DataContractSerializer. 有关提供的序列化支持 DataContractSerializer ,请参阅 数据协定序列化程序

例如,若要指定客户端可以预期包含包含类型参数的 SOAP 错误 Int32FaultContractAttribute 请在服务方法上放置该类型参数。

备注

以下代码示例未设置ProtectionLevelNameNamespace属性。

[OperationContractAttribute]
[FaultContractAttribute(typeof(int))]
int Divide(int arg1, int arg2);
  <OperationContractAttribute(), FaultContractAttribute(GetType(Integer))> _
    Function Divide(ByVal arg1 As Integer, ByVal arg2 As Integer) As Integer
End Interface 'FCADemonstration

然后,在服务方法中,引发一个新 FaultException<TDetail> 值,其中类型参数是包含上述情况下的错误信息 (的类型,即 Int32) 。 例如:

throw new FaultException<int>(4);
Throw New FaultException(Of Integer)(4)

前面的示例非常基本;几乎可以使用代码传递 System.Int32 任何信息,因此此详细信息类型并不是最有用的。 通常,WCF 应用程序指定 SOAP 错误,其中包含特定于客户端错误信息要求的详细信息类型。 有关更多的完整示例,请参见“示例”部分。

备注

如果指定 FaultException<TDetail> 类型参数 System.String的位置,则字符串值将分配给客户端应用程序中的 Detail 属性;客户端无法通过调用 FaultException<TDetail>.ToString 该方法来检索该字符串。 若要在客户端应用程序调用 Exception.ToString 时返回该字符串值,则将在操作内引发 System.ServiceModel.FaultException 异常,并将该字符串传递给构造函数。

若要在异常或FaultException<TDetail>引发时显式控制应用程序的行为,请对某个System.ServiceModel.Description.IServiceBehavior接口实现System.ServiceModel.Dispatcher.IErrorHandler接口,System.ServiceModel.Description.IContractBehaviorSystem.ServiceModel.Description.IEndpointBehavior将其分配给ChannelDispatcher.ErrorHandlers属性。 IErrorHandler 使你能够显式控制生成的 SOAP 错误,以及是否将其发送回客户端。

为了便于调试,可以在代码中设置 ServiceBehaviorAttribute.IncludeExceptionDetailInFaultstrue ,也可以在 ServiceDebugBehavior.IncludeExceptionDetailInFaults 应用程序配置文件中使用。 当启用时,服务会自动将异常信息返回到调用方。 这些错误将客户端显示为 FaultException 异常。

重要

因为托管异常可以公开内部应用程序信息,所以将 ServiceBehaviorAttribute.IncludeExceptionDetailInFaultsServiceDebugBehavior.IncludeExceptionDetailInFaults 设置为 true 可以允许 WCF 客户端获得有关内部服务操作异常的信息,包括个人身份信息或其他敏感信息。

因此,仅建议将 ServiceBehaviorAttribute.IncludeExceptionDetailInFaultsServiceDebugBehavior.IncludeExceptionDetailInFaults 设置为 true 作为一种临时调试服务应用程序的方法。 此外,以这种方式返回未处理的托管异常的方法的 WSDL 并不包含类型为 FaultException<TDetail>String 的协定。 客户端必须预见到发生未知 SOAP 错误(作为 System.ServiceModel.FaultException 对象返回到 WCF 客户端)的可能性,以便正确获取调试信息。

构造函数

FaultContractAttribute(Type)

初始化 FaultContractAttribute 类的新实例。

属性

Action

获取或设置已指定作为操作协定一部分的 SOAP 错误消息的操作。

DetailType

获取包含错误信息的可序列化对象的类型。

HasProtectionLevel

获取一个值,该值指示 SOAP 错误消息是否分配有保护级别。

Name

获取或设置 Web 服务描述语言 (WSDL) 中的错误消息的名称。

Namespace

获取或设置 SOAP 错误的命名空间。

ProtectionLevel

指定 SOAP 错误要求的绑定的保护级别。

TypeId

在派生类中实现时,获取此 Attribute 的唯一标识符。

(继承自 Attribute)

方法

Equals(Object)

返回一个值,该值指示此实例是否与指定的对象相等。

(继承自 Attribute)
GetHashCode()

返回此实例的哈希代码。

(继承自 Attribute)
GetType()

获取当前实例的 Type

(继承自 Object)
IsDefaultAttribute()

在派生类中重写时,指示此实例的值是否是派生类的默认值。

(继承自 Attribute)
Match(Object)

当在派生类中重写时,返回一个指示此实例是否等于指定对象的值。

(继承自 Attribute)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
ToString()

返回表示当前对象的字符串。

(继承自 Object)

显式接口实现

_Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr)

将一组名称映射为对应的一组调度标识符。

(继承自 Attribute)
_Attribute.GetTypeInfo(UInt32, UInt32, IntPtr)

检索对象的类型信息,然后可以使用该信息获取接口的类型信息。

(继承自 Attribute)
_Attribute.GetTypeInfoCount(UInt32)

检索对象提供的类型信息接口的数量(0 或 1)。

(继承自 Attribute)
_Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

提供对某一对象公开的属性和方法的访问。

(继承自 Attribute)

适用于