Obsługa wyjątków w WCF

Wyjątki to błędy występujące w czasie wykonywania; obsługa wyjątków to technika obsługi tych błędów w czasie wykonywania. Do obsługi wyjątków zwykle używa się bloków try, catch i last (nazywanych również blokami wyjątków) w kodzie aplikacji. Jeśli wyjątki nie są prawidłowo obsługiwane w kodzie aplikacji i wystąpił wyjątek w czasie wykonywania, wykonanie aplikacji zostanie przerwane.

Obsługa wyjątków w programie WCF nie jest tak prosta - jesteś ograniczony do wysyłania obiektów .Net przez sieć, a usługa WCF może wysyłać tylko dane serializowane, tj. Komunikaty SOAP do klienta. Wyjątki w programie WCF można obsługiwać na jeden z trzech sposobów:

  1. Korzystanie z FaultException
  2. Korzystanie z IErrorHandler
  3. Korzystanie z returnUnknownExceptionsAsFaults

W tym poście przedstawię dyskusję na temat różnych sposobów przesyłania komunikatów o wyjątkach z usługi WCF do konsumentów usługi.

Rozważ tę prostą usługę WCF.

[Umowa o świadczenie usług]

publiczny interfejs IDBManagerService

    {

        [Umowa Operacyjna]

        void Zapisz (emp. pracownika);

    }

Kontrakt serwisowy IDBManagerService zawiera jeden kontrakt na operację, aby utrwalić obiekt pracownika w bazie danych.

public class DBManagerService: IDBManagerService

    {

        void Save (emp. pracownika)

        {

         próbować

           {

            // Kod przechowujący obiekt pracownika w bazie danych

           }

           catch (wyjątek z wyjątkiem)

           {

               zgłoś nowy wyjątek („Wystąpił błąd podczas zapisywania danych…”);

           }

        }

    }

Załóżmy teraz, że wystąpił błąd podczas łączenia się z bazą danych lub przechowywania obiektu pracownika w bazie danych w czasie, gdy próbujesz korzystać z usługi. Otrzymasz wtedy wyjątek z tym komunikatem: „System.ServiceModel.FaultException: serwer nie mógł przetworzyć żądania z powodu błędu wewnętrznego. Aby uzyskać więcej informacji o błędzie, włącz opcję IncludeExceptionDetailInFaults (z ServiceBehaviorAttribute lub z konfiguracji zachowanie) na serwerze w celu przesłania informacji o wyjątku z powrotem do klienta lub włączyć śledzenie zgodnie z dokumentacją zestawu Microsoft .Net Framework 3.0 SDK i sprawdzić dzienniki śledzenia serwera. ”

Możesz użyć ustawiania elementu includeExceptionDetailInFaults na wartość true w pliku web.config, aby dodatkowe szczegóły wyjątku zostały uwzględnione w błędzie, aby ułatwić Ci sprawdzenie, co faktycznie poszło nie tak.

Możesz to również osiągnąć, pisząc kod. Oto fragment kodu, który ilustruje, jak ustawić tę właściwość na true.

    typeof (ServiceDebugBehavior));

    new ServiceDebugBehavior {IncludeExceptionDetailInFaults = true});

Możesz również ustawić to na true za pomocą tagu ServiceBehavior, jak pokazano poniżej.

[ServiceBehavior (IncludeExceptionDetailInFaults = true)]

public class DBManagerService: IDBManagerService

{

}

Gdy spróbujesz ponownie wykorzystać usługę, zobaczysz dokładniejszy komunikat o wyjątku.

Korzystanie z FaultException

Jeśli jednak musisz przekazać przyjazne dla użytkownika komunikaty o wyjątkach z usługi, należy zgłosić wyjątki błędów. Wyjątki błędów to wyjątki, które są generowane przez usługę WCF, gdy wystąpi wyjątek w czasie wykonywania - takie wyjątki są zwykle używane do przesyłania nietypowych danych o błędach do odbiorców usług. Możesz obsługiwać wyjątki w metodach usług w taki sam sposób, jak w przypadku innych metod, a następnie przekształcić je w wyjątki błędów.

Poniższy fragment kodu przedstawia zaktualizowaną metodę usługi - metoda usługi zgłasza teraz wyjątek błędu.

public class DBManagerService: IDBManagerService

    {

        void Save (emp. pracownika)

        {

            próbować

            {

               // Kod przechowujący obiekt pracownika w bazie danych

            }

            catch (wyjątek z wyjątkiem)

            {

               zgłoś nowy wyjątek FaultException („Wystąpił błąd podczas zapisywania danych…”);

            }

        }

    }

Podczas korzystania z tej usługi należy teraz obsłużyć wyjątek błędu w kodzie. Więcej informacji na temat wyjątków błędów w programie WCF można znaleźć w tym artykule MSDN.

Można również utworzyć niestandardową klasę błędów, która jest oznaczona atrybutem DataContract.

[DataContract]

klasa publiczna CustomFault

{

[DataMember]

public string Source;

[DataMember]

public string ExceptionMessage;

[DataMember]

public string InnerException;

[DataMember]

public string StackTrace;

}

Poniższy fragment kodu ilustruje, jak można użyć klasy CustomFault, aby zgłosić wyjątek FaultException o jednoznacznie określonym typie.

void Save (emp. pracownika)

{

próbować

{

  // Kod, aby zapisać obiekt pracownika w bazie danych

}

catch (wyjątek z wyjątkiem)

{

CustomFault cx = new CustomFault ();

zgłoś nowy wyjątek FaultException (ex, new FaultReason ("To jest wyjątek o jednoznacznie określonym typie błędu"));

}

}

Konieczne byłoby również określenie atrybutu FaultContract w metodzie usługi, która podniosłaby FaultException. Zmodyfikowana metoda Save wyglądałaby tak.

[Umowa o świadczenie usług]

publiczny interfejs IDBManagerService

    {

        [Umowa Operacyjna]

        [FaultContract]

        void Zapisz (emp. pracownika);

    }

Korzystanie z returnUnknownExceptionsAsFaults

Możesz użyć atrybutu returnUnknownExceptionsAsFaults w konfiguracji zachowania usługi, aby automatycznie zgłosić wyjątek jako błąd protokołu SOAP. Poniższy fragment kodu ilustruje, jak możesz to osiągnąć.

                 returnUnknownExceptionsAsFaults = "True">

Globalna obsługa wyjątków

Innym sposobem obsługi wyjątków w programie WCF jest zaimplementowanie interfejsu IErrorHandler w klasie usługi w celu obsługi wszystkich wyjątków globalnie i udostępnienia FaultException zgodnego z protokołem SOAP. Ten interfejs zawiera dwie metody - HandleError i ProvideFault. Podczas gdy pierwsza jest używana do wykonywania pewnych czynności związanych z błędem, druga służy do zwracania komunikatu o błędzie. Zauważ, że możesz także skonfigurować IErrorHandler (włączać lub wyłączać) w pliku konfigurowalnym usługi.