Freigeben über


Erweitern der Kontrolle über fehlerbehandlung und -berichterstellung

Das ErrorHandling-Beispiel veranschaulicht, wie die Kontrolle über die Fehlerbehandlung und Fehlerberichterstattung in einem Windows Communication Foundation (WCF)-Dienst mithilfe der IErrorHandler Schnittstelle erweitert wird. Das Beispiel basiert auf dem Getting Started-Code , der dem Dienst hinzugefügt wurde, um Fehler zu behandeln. Der Client erzwingt mehrere Fehlerbedingungen. Der Dienst fängt die Fehler ab und protokolliert sie in einer Datei.

Hinweis

Die Einrichtungsverfahren und Build-Anweisungen für dieses Beispiel befinden sich am Ende dieses Themas.

Dienste können Fehler abfangen, die Verarbeitung durchführen und beeinflussen, wie Fehler mithilfe der IErrorHandler Schnittstelle gemeldet werden. Die Schnittstelle verfügt über zwei Methoden, die implementiert werden können: ProvideFault(Exception, MessageVersion, Message) und HandleError. Mit der ProvideFault(Exception, MessageVersion, Message) Methode können Sie eine Fehlermeldung hinzufügen, ändern oder unterdrücken, die als Reaktion auf eine Ausnahme generiert wird. Die HandleError Methode ermöglicht die Fehlerverarbeitung im Falle eines Fehlers und steuert, ob zusätzliche Fehlerbehandlung ausgeführt werden kann.

In diesem Beispiel implementiert der CalculatorErrorHandler Typ die IErrorHandler Schnittstelle. Im

HandleError CalculatorErrorHandler-Methode schreibt ein Protokoll des Fehlers in eine Error.txt Textdatei in c:\logs. Beachten Sie, dass das Beispiel den Fehler protokolliert und nicht unterdrückt, sodass er an den Client zurück gemeldet werden kann.

public class CalculatorErrorHandler : IErrorHandler
{
    // Provide a fault. The Message fault parameter can be replaced, or set to
    // null to suppress reporting a fault.

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
    }

    // HandleError. Log an error, then allow the error to be handled as usual.
    // Return true if the error is considered as already handled

    public bool HandleError(Exception error)
    {
        using (TextWriter tw = File.AppendText(@"c:\logs\error.txt"))
        {
            if (error != null)
            {
                tw.WriteLine("Exception: " + error.GetType().Name + " - " + error.Message);
            }
            tw.Close();
        }
        return true;
    }
}

Der ErrorBehaviorAttribute Mechanismus zum Registrieren eines Fehlerhandlers mit einem Dienst ist vorhanden. Dieses Attribut verwendet einen einzelnen Typparameter. Dieser Typ sollte die IErrorHandler Schnittstelle implementieren und einen öffentlichen, leeren Konstruktor aufweisen. Das Attribut instanziiert dann eine Instanz dieses Fehlerhandlertyps und installiert sie im Dienst. Dazu implementieren Sie die IServiceBehavior Schnittstelle und verwenden dann die ApplyDispatchBehavior Methode, um dem Dienst Instanzen des Fehlerhandlers hinzuzufügen.

// This attribute can be used to install a custom error handler for a service.
public class ErrorBehaviorAttribute : Attribute, IServiceBehavior
{
    Type errorHandlerType;

    public ErrorBehaviorAttribute(Type errorHandlerType)
    {
        this.errorHandlerType = errorHandlerType;
    }

    void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
    {
    }

    void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
    {
    }

    void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
    {
        IErrorHandler errorHandler;

        try
        {
            errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
        }
        catch (MissingMethodException e)
        {
            throw new ArgumentException("The errorHandlerType specified in the ErrorBehaviorAttribute constructor must have a public empty constructor.", e);
        }
        catch (InvalidCastException e)
        {
            throw new ArgumentException("The errorHandlerType specified in the ErrorBehaviorAttribute constructor must implement System.ServiceModel.Dispatcher.IErrorHandler.", e);
        }

        foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
        {
            ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
            channelDispatcher.ErrorHandlers.Add(errorHandler);
        }
    }
}

Im Beispiel wird ein Rechnerdienst implementiert. Der Client verursacht absichtlich zwei Fehler für den Dienst, indem Parameter mit unzulässigen Werten bereitgestellt werden. Die CalculatorErrorHandler Schnittstelle verwendet die IErrorHandler Schnittstelle, um die Fehler in einer lokalen Datei zu protokollieren, und ermöglicht es dann, sie an den Client zurückzugeben. Der Client erzwingt eine Trennlinie durch Null und eine Bedingung außerhalb des Bereichs.

try
{
    Console.WriteLine("Forcing an error in Divide");
    // Call the Divide service operation - trigger a divide by 0 error.
    value1 = 22;
    value2 = 0;
    result = proxy.Divide(value1, value2);
    Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
}
catch (FaultException e)
{
    Console.WriteLine("FaultException: " + e.GetType().Name + " - " + e.Message);
}
catch (Exception e)
{
    Console.WriteLine("Exception: " + e.GetType().Name + " - " + e.Message);
}

Wenn Sie das Beispiel ausführen, werden die Vorgangsanforderungen und -antworten im Clientkonsolenfenster angezeigt. Sie sehen die Division durch Null und die Argument-out-of-Range-Bedingungen, die als Fehler gemeldet werden. Drücken Sie im Clientfenster die EINGABETASTE, um den Client zu schließen.

Add(15,3) = 18
Subtract(145,76) = 69
Multiply(9,81) = 729
Forcing an error in Divide
FaultException: FaultException - Invalid Argument: The second argument must not be zero.
Forcing an error in Factorial
FaultException: FaultException - Invalid Argument: The argument must be greater than zero.

Press <ENTER> to terminate client.

Die Datei c:\logs\errors.txt enthält die Vom Dienst protokollierten Informationen zu den Fehlern. Beachten Sie, dass der Dienst zum Schreiben in das Verzeichnis sicherstellen muss, dass der Prozess, unter dem der Dienst ausgeführt wird (in der Regel ASP.NET oder Netzwerkdienst) über die Berechtigung zum Schreiben in das Verzeichnis verfügt.

Fault: Reason = Invalid Argument: The second argument must not be zero.
Fault: Reason = Invalid Argument: The argument must be greater than zero.

So können Sie das Beispiel einrichten, erstellen und ausführen

  1. Stellen Sie sicher, dass Sie das One-Time Setup-Verfahren für die Windows Communication Foundation-Beispieleausgeführt haben.

  2. Befolgen Sie zum Erstellen der Lösung die Anweisungen im Erstellen der Windows Communication Foundation-Beispiele.

  3. Stellen Sie sicher, dass Sie die Datei "c:\logs directory for the error.txt" erstellt haben. Oder ändern Sie den Dateinamen, der in CalculatorErrorHandler.HandleError.

  4. Wenn Sie das Beispiel in einer Konfiguration mit einem Computer oder über Computer hinweg ausführen möchten, folgen Sie den Anweisungen unter Durchführen der Windows Communication Foundation-Beispiele.