Domanda

Attualmente stiamo discutendo se sia meglio lanciare errori su un canale WCF, piuttosto che passare un messaggio che indica lo stato o la risposta da un servizio.

Gli errori vengono forniti con il supporto integrato di WCF in cui è possibile utilizzare i gestori di errori integrati e reagire di conseguenza.Ciò, tuttavia, comporta un sovraccarico poiché la generazione di eccezioni in .NET può essere piuttosto costosa.

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

Abbiamo provato a creare un oggetto messaggio generico da poter utilizzare nei nostri servizi, e questo è ciò che abbiamo ottenuto:

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 restituiscono questo elemento, posso controllare costantemente la proprietà "Success" per determinare se tutto è andato bene.Quindi ho una stringa di messaggio di errore nell'evento che indica che qualcosa è andato storto e un elemento generico contenente un Dto, se necessario.

Le informazioni sull'eccezione dovranno essere registrate in un servizio di registrazione centrale e non restituite dal servizio.

Pensieri?Commenti?Idee?Suggerimenti?

Qualche ulteriore chiarimento sulla mia domanda

Un problema che sto riscontrando con i contratti di colpa è la comunicazione delle regole aziendali.

Ad esempio, se qualcuno accede e il suo account è bloccato, come posso comunicarlo?Il loro accesso ovviamente fallisce, ma fallisce per il motivo "Account bloccato".

Anche io:

A) usa un valore booleano, lancia Fault con l'account del messaggio bloccato

B) restituire AuthenticatedDTO con le informazioni pertinenti

È stato utile?

Soluzione

Ciò tuttavia comporta un sovraccarico poiché la generazione di eccezioni in .NET può essere piuttosto costosa.

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

Di solito mi limito a lanciare eccezioni, poiché comunicano chiaramente che qualcosa è andato storto e Tutto i toolkit dei servizi web hanno un buon modo di gestirli.

Nel tuo esempio lancerei un'eccezione UnauthorizedAccessException con il messaggio "Account bloccato".

Una precisazione: I servizi wcf .NET traducono le eccezioni in FaultContracts per impostazione predefinita, ma è possibile modificare questo comportamento. MSDN: Specificazione e gestione degli errori nei contratti e nei servizi

Altri suggerimenti

Se pensi di chiamare il servizio come chiamare qualsiasi altro metodo, può aiutare a mettere le cose in prospettiva.Immagina se ogni metodo che hai chiamato restituisse uno stato e spettasse a te verificare se è vero o falso.Diventerebbe 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 strutturato di gestione degli errori: puoi separare la logica effettiva dalla 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 attribuiscono maggiori responsabilità al cliente.Potresti sapere che è necessario verificare la presenza di errori nell'oggetto risultato, ma John Doe entra e inizia a chiamare il tuo servizio, ignaro che qualcosa non va perché non viene generata un'eccezione.Questo è un altro grande punto di forza delle eccezioni: ci danno uno schiaffo in faccia quando qualcosa non va e deve essere risolto.

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

Sfortunatamente, al momento sto frequentando un corso di formazione, quindi non posso scrivere una risposta completa, ma per fortuna sto imparando la gestione delle eccezioni nelle applicazioni WCF.Ripubblicherò stasera con maggiori informazioni.(Mi spiace, è una risposta debole)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top