2009-10-08 10 views
23

Ho un servizio WCF distribuito su due o più macchine remote e c'è un'applicazione basata su desktop che viene utilizzata dal client per accedere a qualsiasi servizio wcf.Qual è l'approccio migliore per gestire le eccezioni nel servizio WCF?

Il servizio WCF è connesso a SQL Server 2005 per leggere e scrivere dati. Questo è uno scenario intranet in cui il client deve trovarsi nello stesso dominio.

Ora ci possono essere situazioni in cui il servizio WCF genera eccezioni:

  1. URL non valido
  2. servizio
  3. WCF è giù
  4. SQL Server 2005 non è in esecuzione
  5. client non è sullo stesso dominio
  6. Autenticazione non riuscita
  7. Autorizzazione non riuscita

e molte altre eccezioni.

Per ogni eccezione devo eseguire qualche azione o aggiornare una barra di stato, a seconda dell'eccezione. Ad esempio, se l'autorizzazione non riesce, devo chiedere all'utente di reinserire le proprie credenziali.

Si prega di suggerire il miglior approccio di progettazione per gestire questo.

risposta

32

Si può sicuramente catturare e gestire tutte le eccezioni che si verificano sul tuo classe di servizio e li trasformano in un'eccezione FaultException o FaultException.

In questo modo, non si "guasterà" (o non si distruggerà) il canale di comunicazione tra client e server.

approccio ancora migliore sarebbe quella di implementare l'interfaccia IErrorHandler sulla classe di servizio che fornisce un modo per catturare globalmente tutte le eccezioni che avvengono e fornire un FaultException, invece, che è compatibile SOAP.

È anche possibile trasformare lo IErrorHandler in un comportamento configurabile che può essere attivato o disattivato in configurazione.

Vedi questi articoli e post di blog per maggiori dettagli:

+1

Io non ne so molto su IErrorHandler ma ho letto articoli e post sull'utilizzo di IErrorHandler dice che ha alcuni svantaggi. In alcuni casi, l'eccezione può essere lanciata direttamente dal servizio wcf al client. Mi consiglieresti per IErrorHandler ?? –

+0

Sì, con tutti i mezzi - vorrei ** sempre ** consigliare di utilizzare IErrorHandler. Puoi pubblicare i link a questi articoli che dicono che ha degli svantaggi ?? Mai sentito parlare di questi - Mi piacerebbe investigare ... –

+0

http://stackoverflow.com/questions/265551/wcf-errorhandler Leggi il secondo post !! Non so se è corretto o no ma crea sempre la confusione nella mia mente –

2

È possibile progettare specifici Contratti dati di errore per ciascuno degli scenari di eccezione nel servizio WCF in modo che sia possibile gestire l'errore/eccezione sul lato client rispettivamente.

+0

Sono nuovo di esso può per favore darmi qualche link –

1
try 
{ 
    // Actions 
} 
catch (Exception ex) 
{ 
    // Log the exception 
    // Throw Fault Exception back to client 
    FaultException fe = new FaultException(ex.Message, new FaultCode("Your fault code")); 
    //throw fault exception back to WCF client 
    throw fe; 
}   
6
  1. creare una classe di errore personalizzato che viene contrassegnato con l'attributo DataContract
  2. Segnare il metodo sul servizio interfaccia del contratto con FaultContract. Vale a dire.[FaultContract(typeof(CustomFault))]
  3. Nel metodo di servizio, rilevare eventuali eccezioni interne applicabili e generare un valore FaultException<CustomFault>. In alternativa, come indicato da marc_s, è possibile utilizzare IErrorHandler per associare l'eccezione all'errore.

Personalmente, creo una classe Fault di base che abbia una proprietà Reason e estendo tutti gli errori personalizzati da questa classe. Quando voglio gettare la colpa, che io chiamo:

throw Fault.Create<CustomFault>(new CustomFault("Boo hoo")); 

E 'anche interessante notare che la versione ho le mie classi di guasto (compresa la classe difetto comune) insieme a tutti i miei altri servizi. Questo è solo un problema se la versione del servizio è una preoccupazione, però.

Ecco la classe base di guasto (ho rimosso la convalida degli argomenti per brevità):

[DataContract(Namespace = XmlVersionNamespace.FaultNamespace)] 
public abstract class Fault 
{ 
    internal FaultReason Reason { get; set; } 

    protected Fault(string reasonText) 
    { 
     Reason = new FaultReason(new FaultReasonText(reasonText, CultureInfo.CurrentUICulture)); 
    } 

    public override string ToString() 
    { 
     return Reason.ToString(); 
    } 

    internal static FaultException<TDetail> Create<TDetail>(TDetail fault) where TDetail : Fault 
    { 
     return new FaultException<TDetail>(fault, fault.Reason); 
    } 
} 
+0

Grazie Richard! Potete per favore darmi un esempio se supponiamo che l'autenticazione fallisca. Dammi solo le relazioni relazionali e come gestirai l'app cliente. –

+0

Creerei un AuthenticationFailedFault (estendilo da Fault), passando un messaggio al costruttore di base Fault. Nella tua app client, tieni solo FaultException , poiché AuthenticationFailedFault farà parte del WSDL (purché tu abbia contrassegnato il metodo con [FaultContract]) –

Problemi correlati