2008-09-17 7 views
37

Attualmente stiamo discutendo se sia meglio lanciare i guasti su un canale WCF, anziché passare un messaggio che indica lo stato o la risposta di un servizio.WCF - Guasti/Eccezioni rispetto ai messaggi

Gli errori vengono forniti con il supporto integrato di WCF, dove è possibile utilizzare i gestori di errori incorporati e reagire di conseguenza. Ciò, tuttavia, comporta un sovraccarico poiché le eccezioni di lancio in .NET possono essere piuttosto costose.

I messaggi possono contenere le informazioni necessarie per determinare cosa è successo con la chiamata di servizio senza il sovraccarico di generare un'eccezione. Tuttavia necessita di diverse righe di codice ripetitivo per analizzare il messaggio e determinare le azioni che seguono il suo contenuto.

Abbiamo preso una pugnalata alla creazione di un oggetto messaggio generico potremmo utilizzare nei nostri servizi, e questo è ciò che siamo venuti su con:

public class ReturnItemDTO<T> 
{ 
    [DataMember] 
    public bool Success { get; set; } 

    [DataMember] 
    public string ErrorMessage { get; set; } 

    [DataMember] 
    public T Item { get; set; } 
} 

Se tutte le mie chiamate di servizio restituire questo articolo, posso sempre controllare la proprietà "Success" per determinare se tutto è andato bene. Ho quindi una stringa di messaggi di errore nell'evento che indica che qualcosa è andato storto e un oggetto generico contenente un Dto se necessario.

Le informazioni sulle eccezioni devono essere registrate su un servizio di registrazione centrale e non vengono restituite dal servizio.

Pensieri? Commenti? Idee? Suggerimenti?

Alcuni ulteriori chiarimenti sulla mia domanda

Un problema che sto avendo con contratti di guasto sta comunicando le regole di business.

Come se qualcuno effettuasse l'accesso e il suo account fosse bloccato, come posso comunicarlo? Il loro accesso ovviamente fallisce, ma fallisce a causa del motivo "Account bloccato".

Anch'io:

a) utilizzare un valore booleano, lanciare dei guasti con l'account messaggio bloccato

B) tornare AuthenticatedDTO con informazioni pertinenti

risposta

31

Questo però porta in testa come generare eccezioni in. NET può essere piuttosto costoso.

Si sta serializzando e de-serializzando oggetti in XML e inviandoli su una rete lenta .. il sovraccarico derivante dal lancio di un'eccezione è trascurabile rispetto a quello.

solito attenersi a eccezioni lancio, dal momento che comunicare chiaramente qualcosa è andato storto e tutti toolkit webservice avere un buon modo di gestirli.

Nel tuo esempio vorrei lanciare un oggetto UnauthorizedAccessException con il messaggio "Account bloccato".

Chiarimento: I servizi wcf .NET traducono eccezioni a FaultContracts per impostazione predefinita, ma è possibile modificare questo comportamento.MSDN:Specifying and Handling Faults in Contracts and Services

+0

Non sono d'accordo. Poiché WCF dovrebbe essere indipendente dalla lingua (in qualche modo, almeno) non è possibile garantire che il passaggio di un oggetto Exception lungo il wire non causi problemi di buig per es. Client Java. Il tipo di oggetto FaultContract può garantire l'interoperabilità poiché fa parte delle specifiche OASIS. – ZombieSheep

+4

.NET converte le eccezioni in contratti di errore. Vedi il link che ho aggiunto alla mia risposta. –

+0

Ho sempre avuto l'impressione che il lancio di un'eccezione non fosse necessario. Dal tuo post mi sembra di essere stato tristemente fuorviato. Prima di contrassegnare questo post come l'asnwer, voglio ottenere più opinioni. Ma considerando il tuo input, sembra che il contratto di guasto sia l'opzione migliore – WebDude

0

Prendere seriamente in considerazione l'utilizzo degli oggetti FaultContract e FaultException per aggirare questo problema. Ciò consentirà di inviare messaggi di errore significativi al client, ma solo quando si verifica una condizione di errore.

Sfortunatamente, al momento sono in un corso di formazione, quindi non posso scrivere una risposta completa, ma per fortuna vorrei che sto imparando sulla gestione delle eccezioni nelle applicazioni WCF. Riporterò stasera con più informazioni. (Spiacente, è una risposta debole)

6

Se si pensa di chiamare il servizio come se si chiamasse un altro metodo, può essere utile mettere le cose in prospettiva. Immagina se ogni metodo che hai chiamato abbia restituito uno stato e tu spetti a te verificare se sia vero o falso. Sarebbe piuttosto noioso.

result = CallMethod(); 
if (!result.Success) handleError(); 

result = CallAnotherMethod(); 
if (!result.Success) handleError(); 

result = NotAgain(); 
if (!result.Success) handleError(); 

Questo è uno dei punti di forza di un sistema di gestione degli errori strutturata, è che si può separare la logica reale dal vostro gestione degli errori. Non devi continuare a controllare, sai che è stato un successo se non è stata lanciata alcuna eccezione.

try 
{ 
    CallMethod(); 
    CallAnotherMethod(); 
    NotAgain(); 
} 
catch (Exception e) 
{ 
    handleError(); 
} 

Allo stesso tempo, restituendo un risultato si sta attribuendo maggiore responsabilità al cliente. È probabile che tu sappia controllare gli errori nell'oggetto risultato, ma John Doe entra e inizia a chiamare al tuo servizio, ignaro che qualcosa non va perché non viene lanciata un'eccezione. Questo è un altro grande punto di forza delle eccezioni è che ci danno un buon schiaffo in faccia quando qualcosa non va e deve essere curato.