简体   繁体   English

我一直在客户端获得WCF服务处于故障状态。 如何在不破坏WCF服务的情况下捕获WCF异常?

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

I have a WCF service multiple UIs consume. 我有一个WCF服务多个UI消耗。 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 side and send it to the client. 我没有在服务器端捕获异常并将其发送到客户端。

On the client (asp.net webpage), I get to see the exception - User was unable to access the database, login failed. 在客户端(asp.net网页)上,我看到异常 - 用户无法访问数据库,登录失败。 This is all good. 这一切都很好。 But... if I make a call to the WCF service again, I get the exception that the service is in faulted state. 但是......如果我再次调用WCF服务,我会得到服务处于故障状态的异常。 Only open is to restart the entire WCF service. 只有open才能重新启动整个WCF服务。 WCF service is hosted as a windows service. WCF服务作为Windows服务托管。

What is 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? 捕获异常的最佳方法是什么,在服务器端记录异常,将异常详细信息发送回客户端而不破坏服务? Thanks 谢谢

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. 正如其他人所指出的那样,必须通过调用Abort()来中止故障通道 - 它不能被关闭而且不能再次使用。

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 . 要解决问题的其他部分,“捕获异常的最佳方法,在服务器端记录异常,将异常详细信息发送回客户端而不破坏服务?”,您需要使用FaultException类

Additionally, you can use the IErrorHandler Interface to wire up your service host to catch any exceptions that were not otherwise caught (ie, a global error handler). 此外,您可以使用IErrorHandler接口连接服务主机以捕获未捕获的任何异常(即,全局错误处理程序)。 There are many examples of how to do this on the net - just google for WCF IErrorHandler. 有很多关于如何在网上执行此操作的示例 - 只需google for WCF IErrorHandler。

Here's a couple: 这是一对夫妇:

WCF Exception Handling with IErrorHandler 使用IErrorHandler进行WCF异常处理

WCF Extensibility – IErrorHandler WCF可扩展性 - IErrorHandler

You can use this code to create a wrapper class that will properly handle WCF exceptions: 您可以使用此代码创建一个能够正确处理WCF异常的包装类:

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

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#: 请参阅以下链接,其中讨论了WCF客户端应如何捕获故障/异常以及C#中使用'using'语句可能遇到的潜在问题:

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

Baiscally you need to call Abort() on your client proxy. 通过Baiscally,您需要在客户端代理上调用Abort()。 This will immediately set the state of the proxy to Closed. 这将立即将代理的状态设置为Closed。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM