2011-11-18 11 views
8

Mam usługę WCF wielu użytkowników zużywają. Gdy użytkownik nie może uzyskać dostępu do bazy danych, otrzymuję nieautoryzowany wyjątek z bazy danych. Nie łapię wyjątku po stronie serwera i wysyłam go do klienta.Ciągle uzyskiwanie usługi WCF jest w stanie błędu po stronie klienta. Jak powinienem wychwycić wyjątki WCF, bez łamania mojej usługi WCF?

Na kliencie (strona asp.net) dostaję wyjątek - Użytkownik nie może uzyskać dostępu do bazy danych, logowanie nie powiodło się. To wszystko dobrze. Ale ... jeśli ponownie wykonam wywołanie usługi WCF, otrzymuję wyjątek, że usługa jest w stanie błędu. Tylko otwarte jest ponowne uruchomienie całej usługi WCF. Usługa WCF jest obsługiwana jako usługa systemu Windows.

Jaki jest najlepszy sposób na wychwycenie wyjątków, zarejestrowanie wyjątku po stronie serwera, przesłanie szczegółowych informacji o wyjątku do klienta bez przerywania usługi? Dzięki

+1

spróbuj faultcontract. – Radhi

Odpowiedz

6

Nieobsłużone wyjątki będą skarżyć się na komunikację kanał. Jak zauważyli inni, uszkodzony kanał musi zostać przerwany przez wywołanie Abort() - nie można go zamknąć i nie można go użyć ponownie.

Aby zaadresować drugą część pytania, "najlepszy sposób na wychwycenie wyjątków, zaloguj się po stronie serwera po stronie wyjątku, wyślij szczegóły wyjątku do klienta bez zerwania usługi?", Musisz użyć FaultException Class.

Ponadto można użyć usługi IErrorHandler Interface do podłączenia hosta usługi w celu wychwycenia wyjątków, które nie zostały w inny sposób przechwycone (tj. Globalnej procedury obsługi błędów). Jest wiele przykładów tego, jak to zrobić w sieci - wystarczy google dla WCF IErrorHandler.

Oto kilka:

WCF Exception Handling with IErrorHandler

WCF Extensibility – IErrorHandler

+0

dzięki. kiedy powinienem złapać wyjątki i zgłaszać wyjątki błędów? w kontraktach operacyjnych lub w kodzie usługi Windows, który tworzy obiekty hosta usług? – InfoLearner

+0

Wyłapujesz wyjątek w usłudze, przekształcisz go do postaci umowy o błędzie, a następnie klient (lub usługa Windows) może wychwycić wyjątek błędu w bloku try-catch. – Tim

+0

Bardzo jasne, dziękuję –

1

Patrz poniższy link, który opowiada o tym, jak klienci WCF powinna złapać błędów/wyjątki i potencjalnych problemów, które mogą napotkasz z „wykorzystaniem” oświadczenie w C#:

http://msdn.microsoft.com/en-us/library/aa355056.aspx

Baiscally trzeba wywołaj Abort() na swoim proxy klienta. Spowoduje to natychmiastowe ustawienie stanu proxy na Zamknięty.

+0

o świetnie. myślisz, że można wrzucać wyjątki z powrotem do klienta z usługi wcf? – InfoLearner

+0

Myślę, że to naprawdę zależy od rodzaju tworzonej aplikacji i ogólnej strategii obsługi wyjątków. Biorąc to pod uwagę, jeśli jest to aplikacja skierowana do użytkownika końcowego, prawdopodobnie chcesz poinformować go, że coś poszło nie tak. –

2

Można użyć tego kodu, aby utworzyć klasy otoki, który będzie prawidłowo obsługiwać WCF wyjątki:

public class ServiceProxyHelper<TProxy, TChannel> : IDisposable 
    where TProxy : ClientBase<TChannel>, new() 
    where TChannel : class 
{ 
    /// 
    /// Private instance of the WCF service proxy. 
    /// 
    private TProxy _proxy; 

    /// 
    /// Gets the WCF service proxy wrapped by this instance. 
    /// 
    public TProxy Proxy 
    { 
     get 
     { 
      if (_proxy != null) 
      { 
       return _proxy; 
      } 
      else 
      { 
       throw new ObjectDisposedException("ServiceProxyHelper"); 
      } 
     } 
    } 

    public TChannel Channel { get; private set; } 

    /// 
    /// Constructs an instance. 
    /// 
    public ServiceProxyHelper() 
    { 
     _proxy = new TProxy(); 
    } 

    /// 
    /// Disposes of this instance. 
    /// 
    public void Dispose() 
    { 
     try 
     { 
      if (_proxy != null) 
      { 
       if (_proxy.State != CommunicationState.Faulted) 
       { 
        _proxy.Close(); 
       } 
       else 
       { 
        _proxy.Abort(); 
       } 
      } 
     } 
     catch (CommunicationException) 
     { 
      _proxy.Abort(); 
     } 
     catch (TimeoutException) 
     { 
      _proxy.Abort(); 
     } 
     catch (Exception) 
     { 
      _proxy.Abort(); 
      throw; 
     } 
     finally 
     { 
      _proxy = null; 
     } 
    } 
} 

Następnie można wywołać usługę tak:

using (ServiceProxyHelper<EmailServiceClient, EmailService> svc = 
    new ServiceProxyHelper<EmailServiceClient, EmailService>()) 
{ 
    svc.Proxy.SendMail(fromAddress, fromName, toEmail, toName, message); 
} 
Powiązane problemy