Kontrakt błędu
W przykładzie Faults pokazano, jak przekazać informacje o błędach z usługi do klienta. Przykład jest oparty na przewodniku Wprowadzenie, z dodatkowym kodem dodanym do usługi w celu przekonwertowania wyjątku wewnętrznego na błąd. Klient próbuje wykonać dzielenie przez zero, aby wymusić błąd w usłudze.
Uwaga
Procedura instalacji i instrukcje kompilacji dla tego przykładu znajdują się na końcu tego tematu.
Kontrakt kalkulatora został zmodyfikowany tak, aby zawierał element FaultContractAttribute , jak pokazano w poniższym przykładowym kodzie.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
int Add(int n1, int n2);
[OperationContract]
int Subtract(int n1, int n2);
[OperationContract]
int Multiply(int n1, int n2);
[OperationContract]
[FaultContract(typeof(MathFault))]
int Divide(int n1, int n2);
}
Atrybut FaultContractAttribute wskazuje, że Divide
operacja może zwrócić błąd typu MathFault
. Błąd może być dowolnego typu, który można serializować. W tym przypadku MathFault
parametr jest kontraktem danych w następujący sposób:
[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; }
}
}
Metoda Divide
zgłasza FaultException<TDetail> wyjątek, gdy wystąpi wyjątek dzielenia przez zero, jak pokazano w poniższym przykładowym kodzie. Ten wyjątek powoduje wysłanie błędu do klienta.
public int Divide(int n1, int n2)
{
try
{
return n1 / n2;
}
catch (DivideByZeroException)
{
MathFault mf = new MathFault();
mf.operation = "division";
mf.problemType = "divide by zero";
throw new FaultException<MathFault>(mf);
}
}
Kod klienta wymusza błąd, żądając dzielenia o zero. Po uruchomieniu przykładu żądania operacji i odpowiedzi są wyświetlane w oknie konsoli klienta. Podział według zera jest zgłaszany jako błąd. Naciśnij klawisz ENTER w oknie klienta, aby zamknąć klienta.
Add(15,3) = 18
Subtract(145,76) = 69
Multiply(9,81) = 729
FaultException<MathFault>: Math fault while doing division. Problem: divide by zero
Press <ENTER> to terminate client.
Klient robi to, przechwytując odpowiedni FaultException<MathFault>
wyjątek:
catch (FaultException<MathFault> e)
{
Console.WriteLine("FaultException<MathFault>: Math fault while doing " + e.Detail.operation + ". Problem: " + e.Detail.problemType);
client.Abort();
}
Domyślnie szczegóły nieoczekiwanych wyjątków nie są wysyłane do klienta, aby zapobiec ucieczce z bezpiecznej granicy usługi przez implementację usługi. FaultContract
zapewnia sposób opisywania błędów w umowie i oznaczania określonych typów wyjątków odpowiednio do transmisji do klienta. FaultException<T>
zapewnia mechanizm czasu wykonywania do wysyłania błędów do użytkowników.
Jednak przydatne jest sprawdzenie wewnętrznych szczegółów błędu usługi podczas debugowania. Aby wyłączyć wcześniej opisane bezpieczne zachowanie, można wskazać, że szczegóły każdego nieobsługiwanego wyjątku na serwerze powinny być uwzględnione w błędzie, który jest wysyłany do klienta. Można to zrobić, ustawiając wartość IncludeExceptionDetailInFaults .true
Możesz ustawić go w kodzie lub w konfiguracji, jak pokazano w poniższym przykładzie.
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
Ponadto zachowanie musi być skojarzone z usługą przez ustawienie behaviorConfiguration
atrybutu usługi w pliku konfiguracji na wartość "CalculatorServiceBehavior".
Aby przechwycić takie błędy na kliencie, należy przechwycić nieogólne FaultException .
To zachowanie powinno być używane tylko do celów debugowania i nigdy nie powinno być włączone w środowisku produkcyjnym.
Aby skonfigurować, skompilować i uruchomić przykład
Upewnij się, że wykonano procedurę instalacji jednorazowej dla przykładów programu Windows Communication Foundation.
Aby skompilować wersję rozwiązania w języku C# lub Visual Basic .NET, postępuj zgodnie z instrukcjami w temacie Building the Windows Communication Foundation Samples (Tworzenie przykładów programu Windows Communication Foundation).
Aby uruchomić przykład w konfiguracji pojedynczej lub między maszynami, postępuj zgodnie z instrukcjami w temacie Uruchamianie przykładów programu Windows Communication Foundation.