2011-11-18 15 views
8

Tengo un servicio WCF que consumen varias IU. Cuando el usuario no puede acceder a la base de datos, recibo una excepción no autorizada de la base de datos. No entiendo la excepción del lado del servidor y se la envío al cliente.Sigo recibiendo servicio WCF está en estado de falla en el lado del cliente. ¿Cómo debo detectar las excepciones WCF sin romper mi servicio WCF?

En el cliente (página web asp.net), puedo ver la excepción: el usuario no ha podido acceder a la base de datos, el inicio de sesión ha fallado. Esto está todo bien. Pero ... si vuelvo a llamar al servicio WCF, recibo la excepción de que el servicio está en estado de error. Solo abrir es reiniciar todo el servicio WCF. El servicio WCF está alojado como un servicio de Windows.

¿Cuál es la mejor manera de detectar las excepciones, registrar la excepción en el servidor, enviar los detalles de la excepción de vuelta al cliente sin interrumpir el servicio? Gracias

+1

intentar usar faultcontract. – Radhi

Respuesta

6

Las excepciones no controladas se quejar de la comunicación canal. Como han señalado otros, un canal con falla se debe cancelar llamando al Abort(); no se puede cerrar y no se puede volver a usar.

Para abordar la otra parte de su pregunta, la "mejor forma de detectar las excepciones, registrar la excepción en el servidor, enviar los detalles de la excepción al cliente sin interrumpir el servicio?", Necesita usar FaultException Class.

Además, puede usar el IErrorHandler Interface para conectar su servidor de servicio para detectar cualquier excepción que no haya sido detectada (es decir, un controlador de error global). Hay muchos ejemplos de cómo hacer esto en la red: solo google para WCF IErrorHandler.

Aquí hay un par:

WCF Exception Handling with IErrorHandler

WCF Extensibility – IErrorHandler

+0

gracias. ¿Cuándo debería detectar las excepciones y lanzar excepciones de fallas? en contratos de operación o en el código de inicio de servicio de Windows que crea objetos host de servicio? – InfoLearner

+0

Detectará la excepción en el servicio, la serializará como un contrato de falla y luego el cliente (o el servicio de Windows) puede detectar la excepción de falla en un bloque try-catch. – Tim

+0

Muy claro, gracias –

1

Véase el siguiente enlace que habla sobre cómo los clientes WCF deben ponerse faltas/excepciones y problemas potenciales es posible que encuentre con la declaración de 'utilizar' en C#:

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

baiscally usted necesita llama Abort() en tu proxy de cliente. Esto establecerá inmediatamente el estado del proxy en Cerrado.

+0

genial. ¿Cree que está bien devolver las excepciones al cliente desde el servicio wcf? – InfoLearner

+0

Creo que eso realmente depende del tipo de aplicación que esté construyendo y cuál es su estrategia general de manejo de excepciones. Dicho esto, si se trata de una aplicación para el usuario final, es probable que desee hacerles saber que algo salió mal. –

2

Puede utilizar este código para crear una clase contenedora que manejará adecuadamente WCF excepciones:

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; 
     } 
    } 
} 

A continuación, puede llamar a un servicio como este:

using (ServiceProxyHelper<EmailServiceClient, EmailService> svc = 
    new ServiceProxyHelper<EmailServiceClient, EmailService>()) 
{ 
    svc.Proxy.SendMail(fromAddress, fromName, toEmail, toName, message); 
} 
Cuestiones relacionadas