Condividi tramite


Estensione del controllo sulla gestione degli errori e sulla creazione di report

L'esempio ErrorHandling illustra come estendere il controllo sulla gestione degli errori e la segnalazione degli errori in un servizio Windows Communication Foundation (WCF) tramite l'interfaccia IErrorHandler . L'esempio si basa su Getting Started con del codice aggiuntivo aggiunto al servizio per gestire gli errori. Il client forza diverse condizioni di errore. Il servizio intercetta gli errori e li registra in un file.

Annotazioni

La procedura di installazione e le istruzioni di compilazione per questo esempio si trovano alla fine di questo argomento.

I servizi possono intercettare errori, eseguire l'elaborazione e influire sulla modalità di segnalazione degli errori tramite l'interfaccia IErrorHandler . L'interfaccia include due metodi che possono essere implementati: ProvideFault(Exception, MessageVersion, Message) e HandleError. Il ProvideFault(Exception, MessageVersion, Message) metodo consente di aggiungere, modificare o eliminare un messaggio di errore generato in risposta a un'eccezione. Il HandleError metodo consente l'elaborazione degli errori in caso di errore e controlla se è possibile eseguire ulteriori operazioni di gestione degli errori.

In questo esempio il CalculatorErrorHandler tipo implementa l'interfaccia IErrorHandler . Nel

HandleError metodo, CalculatorErrorHandler scrive un log dell'errore in un file di testo Error.txt in c:\logs. Si noti che l'esempio registra l'errore e non lo elimina, consentendo di riportarlo al 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;
    }
}

ErrorBehaviorAttribute viene utilizzato come meccanismo per registrare un gestore di errori con un servizio. Questo attributo accetta un singolo parametro di tipo. Tale tipo deve implementare l'interfaccia IErrorHandler e deve avere un costruttore pubblico e vuoto. L'attributo crea quindi un'istanza del tipo di gestore errori e la installa nel servizio. A tale scopo, implementa l'interfaccia IServiceBehavior e quindi usa il ApplyDispatchBehavior metodo per aggiungere istanze del gestore errori al servizio.

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

L'esempio implementa un servizio di calcolo. Il client causa deliberatamente due errori nel servizio fornendo parametri con valori non validi. CalculatorErrorHandler usa l'interfaccia IErrorHandler per registrare gli errori in un file locale e quindi consente di riportarli al client. Il client forza una divisione per zero e una condizione di argomento non compreso nell'intervallo.

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

Quando si esegue l'esempio, le richieste e le risposte dell'operazione vengono visualizzate nella finestra della console client. La divisione viene visualizzata per zero e le condizioni di argomento non compreso nell'intervallo vengono segnalate come errori. Premere INVIO nella finestra del client per chiudere il client.

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.

Il file c:\logs\errors.txt contiene le informazioni registrate sugli errori dal servizio. Si noti che per consentire al servizio di scrivere nella directory è necessario assicurarsi che il processo in cui il servizio sia in esecuzione (in genere ASP.NET o servizio di rete) disponga dell'autorizzazione per la scrittura nella directory.

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

Per configurare, compilare ed eseguire l'esempio

  1. Assicurati di aver eseguito la procedura di installazione di One-Time per gli esempi di Windows Communication Foundation.

  2. Per compilare la soluzione, seguire le istruzioni riportate in Compilazione degli esempi di Windows Communication Foundation.

  3. Assicurarsi di aver creato il file c:\logs directory for the error.txt. In alternativa, modificare il nome del file usato in CalculatorErrorHandler.HandleError.

  4. Per eseguire l'esempio in una configurazione con computer singolo o incrociato, seguire le istruzioni riportate in Esecuzione degli esempi di Windows Communication Foundation.