Definindo e especificando falhas
As falhas SOAP transmitem informações de condição de erro de um serviço para um cliente e, no caso duplex, de um cliente para um serviço de forma interoperável. Este tópico discute quando e como definir conteúdo de falha personalizado e especificar quais operações podem retorná-los. Para obter mais informações sobre como um serviço, ou cliente duplex, pode enviar essas falhas e como um cliente ou aplicativo de serviço lida com essas falhas, consulte Enviando e recebendo falhas. Para obter uma visão geral do tratamento de erros em aplicativos do Windows Communication Foundation (WCF), consulte Especificando e manipulando falhas em contratos e serviços.
Descrição geral
Falhas SOAP declaradas são aquelas em que uma operação tem um System.ServiceModel.FaultContractAttribute que especifica um tipo de falha SOAP personalizado. Falhas SOAP não declaradas são aquelas que não são especificadas no contrato para uma operação. Este tópico ajuda você a identificar essas condições de erro e criar um contrato de falha para seu serviço que os clientes podem usar para lidar corretamente com essas condições de erro quando notificados por falhas SOAP personalizadas. As tarefas básicas são, pela ordem:
Defina as condições de erro que um cliente do seu serviço deve conhecer.
Defina o conteúdo personalizado das falhas SOAP para essas condições de erro.
Marque suas operações para que as falhas SOAP específicas que elas lançam sejam expostas aos clientes no WSDL.
Definindo condições de erro que os clientes devem conhecer
As falhas SOAP são mensagens descritas publicamente que carregam informações de falha para uma operação específica. Como eles são descritos junto com outras mensagens de operação no WSDL, os clientes sabem e, portanto, esperam lidar com essas falhas ao invocar uma operação. Mas como os serviços WCF são escritos em código gerenciado, decidir quais condições de erro no código gerenciado devem ser convertidas em falhas e devolvidas ao cliente oferece a oportunidade de separar condições de erro e bugs em seu serviço da conversa formal de erro que você tem com um cliente.
Por exemplo, o exemplo de código a seguir mostra uma operação que usa dois inteiros e retorna outro inteiro. Várias exceções podem ser lançadas aqui, portanto, ao projetar o contrato de falha, você deve determinar quais condições de erro são importantes para o seu cliente. Nesse caso, o serviço deve detetar a System.DivideByZeroException exceção.
[ServiceContract]
public class CalculatorService
{
[OperationContract]
int Divide(int a, int b)
{
if (b==0) throw new Exception("Division by zero!");
return a/b;
}
}
<ServiceContract> _
Public Class CalculatorService
<OperationContract> _
Public Function Divide(a As Integer, b As Integer) As Integer
If b = 0 Then Throw New DivideByZeroException("Division by zero!")
Return a / b
End Function
End Class
No exemplo anterior, a operação pode retornar uma falha SOAP personalizada que é específica para dividir por zero, uma falha personalizada que é específica para operações matemáticas, mas que contém informações específicas para dividir por zero, várias falhas para várias situações de erro diferentes ou nenhuma falha SOAP.
Definir o conteúdo das condições de erro
Depois que uma condição de erro tiver sido identificada como uma que pode retornar utilmente uma falha SOAP personalizada, a próxima etapa é definir o conteúdo dessa falha e garantir que a estrutura de conteúdo possa ser serializada. O exemplo de código na seção anterior mostra um erro específico para uma Divide
operação, mas se houver outras operações no Calculator
serviço, uma única falha SOAP personalizada pode informar o cliente de todas as condições de erro da calculadora, Divide
incluídas. O exemplo de código a seguir mostra a criação de uma falha SOAP personalizada, MathFault
, que pode relatar erros feitos usando todas as operações matemáticas, incluindo Divide
. Embora a classe possa especificar uma operação (a Operation
propriedade) e um valor que descreva o problema (a ProblemType
propriedade), a classe e essas propriedades devem ser serializáveis para serem transferidas para o cliente em uma falha SOAP personalizada. Portanto, os System.Runtime.Serialization.DataContractAttribute atributos e System.Runtime.Serialization.DataMemberAttribute são usados para tornar o tipo e suas propriedades serializáveis e o mais interoperáveis possível.
// Define a math fault data contract
[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public class MathFault
{
private string operation;
private string problemType;
[DataMember]
public string Operation
{
get { return operation; }
set { operation = value; }
}
[DataMember]
public string ProblemType
{
get { return problemType; }
set { problemType = value; }
}
}
' Define a math fault data contract
<DataContract([Namespace]:="http://Microsoft.ServiceModel.Samples")> _
Public Class MathFault
Private m_operation As String
Private m_problemType As String
<DataMember()> _
Public Property Operation() As String
Get
Return m_operation
End Get
Set(ByVal value As String)
m_operation = value
End Set
End Property
<DataMember()> _
Public Property ProblemType() As String
Get
Return m_problemType
End Get
Set(ByVal value As String)
m_problemType = value
End Set
End Property
End Class
Para obter mais informações sobre como garantir que seus dados sejam serializáveis, consulte Especificando a transferência de dados em contratos de serviço. Para obter uma lista do suporte de serialização fornecido System.Runtime.Serialization.DataContractSerializer , consulte Tipos suportados pelo serializador de contrato de dados.
Marcar operações para estabelecer o contrato de falha
Depois que uma estrutura de dados serializável que é retornada como parte de uma falha SOAP personalizada é definida, a última etapa é marcar seu contrato de operação como lançando uma falha SOAP desse tipo. Para fazer isso, use o System.ServiceModel.FaultContractAttribute atributo e passe o tipo do tipo de dados personalizados que você construiu. O exemplo de código a seguir mostra como usar o FaultContractAttribute atributo para especificar que a Divide
operação pode retornar uma falha SOAP do tipo MathFault
. Outras operações baseadas em matemática agora também podem especificar que podem retornar um MathFault
arquivo .
[OperationContract]
[FaultContract(typeof(MathFault))]
int Divide(int n1, int n2);
<OperationContract()> _
<FaultContract(GetType(MathFault))> _
Function Divide(ByVal n1 As Integer, ByVal n2 As Integer) As Integer
Uma operação pode especificar que retorna mais de uma falha personalizada marcando essa operação com mais de um FaultContractAttribute atributo.
O próximo passo, para implementar o contrato de falha na implementação da sua operação, é descrito no tópico Envio e recebimento de falhas.
Considerações sobre SOAP, WSDL e interoperabilidade
Em algumas circunstâncias, especialmente ao interoperar com outras plataformas, pode ser importante controlar a maneira como uma falha aparece em uma mensagem SOAP ou a maneira como ela é descrita nos metadados WSDL.
O FaultContractAttribute atributo tem uma Name propriedade que permite o controle do nome do elemento de falha WSDL que é gerado nos metadados para essa falha.
De acordo com o padrão SOAP, uma falha pode ter um Action
, a Code
e um Reason
. O Action
é controlado pela Action propriedade. A Code propriedade e Reason a System.ServiceModel.FaultException propriedade são ambas propriedades da classe, que é a classe pai do genérico System.ServiceModel.FaultException<TDetail>. A Code
propriedade inclui um SubCode membro.
Ao acessar não serviços que geram falhas, existem algumas limitações. O WCF suporta apenas falhas com tipos de detalhes que o esquema descreve e que são compatíveis com contratos de dados. Por exemplo, como mencionado acima, o WCF não oferece suporte a falhas que usam atributos XML em seus tipos de detalhes ou falhas com mais de um elemento de nível superior na seção de detalhes.
Consulte também
- FaultContractAttribute
- DataContractAttribute
- DataMemberAttribute
- Especificação e Tratamento de Falhas em Contratos e Serviços
- Envio e recebimento de falhas
- Como: Declarar falhas em contratos de serviço
- Noções básicas sobre o nível de proteção
- Como: Definir a propriedade ProtectionLevel
- Especificando a transferência de dados em contratos de serviços