I keep getting WCF service is in faulted state on the client side. How should I catch WCF exceptions, without breaking my WCF service?

前端 未结 3 1860
故里飘歌
故里飘歌 2021-02-04 15:48

I have a WCF service multiple UIs consume. When the user is unable to access the database, I get Unauthorised exception from the DB. I don\'t catch the exception on the server

相关标签:
3条回答
  • 2021-02-04 16:11

    Unhandled exceptions will fault the communication channel. As others have pointed out, a faulted channel must be aborted by calling Abort() - it can't be closed and it can't be used again.

    To address the other part of your question, the "best way to catch the exceptions, log the exception on server side, send the exception details back to the client without breaking the service?", you need to use FaultException Class.

    Additionally, you can use the IErrorHandler Interface to wire up your service host to catch any exceptions that were not otherwise caught (i.e., a global error handler). There are many examples of how to do this on the net - just google for WCF IErrorHandler.

    Here's a couple:

    WCF Exception Handling with IErrorHandler

    WCF Extensibility – IErrorHandler

    0 讨论(0)
  • 2021-02-04 16:17

    See the following link which talks about how WCF clients should catch faults/exceptions and potential problems you may run into with the 'using' statement in C#:

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

    Baiscally you need to call Abort() on your client proxy. This will immediately set the state of the proxy to Closed.

    0 讨论(0)
  • 2021-02-04 16:36

    You can use this code to create a wrapper class that will properly handle WCF exceptions:

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

    You can then call a service like this:

    using (ServiceProxyHelper<EmailServiceClient, EmailService> svc =
       new ServiceProxyHelper<EmailServiceClient, EmailService>())
    {
       svc.Proxy.SendMail(fromAddress, fromName, toEmail, toName, message);
    }
    
    0 讨论(0)
提交回复
热议问题