Delen via


Controle over foutafhandeling en rapportage uitbreiden

In het voorbeeld ErrorHandling ziet u hoe u de controle over foutafhandeling en foutrapportage in een WCF-service (Windows Communication Foundation) kunt uitbreiden met behulp van de IErrorHandler interface. Het voorbeeld is gebaseerd op de Aan de slag met enkele extra code die aan de service is toegevoegd om fouten te verwerken. De client dwingt verschillende foutvoorwaarden af. De service onderschept de fouten en registreert deze in een bestand.

Notitie

De installatieprocedure en build-instructies voor dit voorbeeld bevinden zich aan het einde van dit onderwerp.

Services kunnen fouten onderscheppen, verwerking uitvoeren en invloed hebben op de wijze waarop fouten worden gerapporteerd met behulp van de IErrorHandler interface. De interface heeft twee methoden die kunnen worden geïmplementeerd: ProvideFault(Exception, MessageVersion, Message) en HandleError. Met de ProvideFault(Exception, MessageVersion, Message) methode kunt u een foutbericht toevoegen, wijzigen of onderdrukken dat wordt gegenereerd als reactie op een uitzondering. Met HandleError de methode kan foutverwerking plaatsvinden in het geval van een fout en bepaalt of er aanvullende foutafhandeling kan worden uitgevoerd.

In dit voorbeeld implementeert het CalculatorErrorHandler type de IErrorHandler interface. In de

HandleErrorCalculatorErrorHandler de methode schrijft een logboek van de fout naar een Error.txt tekstbestand in c:\logs. Houd er rekening mee dat het voorbeeld de fout registreert en deze niet onderdrukt, zodat deze kan worden gerapporteerd aan de client.

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;
    }
}

Het ErrorBehaviorAttribute bestaat als mechanisme voor het registreren van een fouthandler bij een service. Dit kenmerk heeft één typeparameter. Dit type moet de IErrorHandler interface implementeren en een openbare, lege constructor hebben. Het kenmerk instantieert vervolgens een exemplaar van dat fouthandlertype en installeert het in de service. Dit doet u door de IServiceBehavior interface te implementeren en vervolgens de ApplyDispatchBehavior methode te gebruiken om exemplaren van de fouthandler toe te voegen aan de service.

// 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);
        }
    }
}

In het voorbeeld wordt een rekenmachineservice geïmplementeerd. De client veroorzaakt opzettelijk twee fouten die op de service optreden door parameters met illegale waarden op te geven. De CalculatorErrorHandler interface maakt gebruik van de IErrorHandler interface om de fouten in een lokaal bestand te registreren en deze vervolgens weer aan de client te melden. De client dwingt een deel af door nul en een argument buiten bereikvoorwaarde.

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);
}

Wanneer u het voorbeeld uitvoert, worden de bewerkingsaanvragen en -antwoorden weergegeven in het clientconsolevenster. U ziet de deling door nul en de argument-out-of-range-voorwaarden die worden gerapporteerd als fouten. Druk op Enter in het clientvenster om de client af te sluiten.

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.

Het bestand c:\logs\errors.txt bevat de informatie die is vastgelegd over de fouten van de service. Houd er rekening mee dat voor de service die naar de map moet worden geschreven, u ervoor moet zorgen dat het proces waaronder de service wordt uitgevoerd (meestal ASP.NET of netwerkservice) gemachtigd is om naar de map te schrijven.

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

Het voorbeeld instellen, compileren en uitvoeren

  1. Zorg ervoor dat u de eenmalige installatieprocedure voor de Windows Communication Foundation-voorbeelden hebt uitgevoerd.

  2. Volg de instructies in Het bouwen van de Windows Communication Foundation-voorbeelden om de oplossing te bouwen.

  3. Zorg ervoor dat u de map c:\logs voor het error.txt-bestand hebt gemaakt. Of wijzig de bestandsnaam die wordt gebruikt in CalculatorErrorHandler.HandleError.

  4. Als u het voorbeeld wilt uitvoeren in een configuratie met één of meerdere computers, volgt u de instructies in Het uitvoeren van de Windows Communication Foundation-voorbeelden.