通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信

通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它处于Faulted状态。

这个错误到底是什么,我怎么去解决呢?

你得到这个错误是因为你在你的服务器端发生了一个.NETexception,而你没有捕获并处理它,也没有将它转换为SOAP错误。

现在,由于服务器端“轰炸”出来,WCF运行时有“故障”的渠道 – 例如,客户端和服务器之间的通信链路是不可用的 – 毕竟,它看起来像你的服务器刚刚爆炸,所以你不能沟通它再一次。

所以你需要做的是:

  • 总是捕捉并处理服务器端错误 – 不要让.NETexception从服务器传输到客户端 – 总是将这些exception封装到可互操作的SOAP错误中。 查看WCF IErrorHandler接口并在服务器端实现它

  • 如果您要从客户端向您的频道发送第二条消息,请确保该频道不处于故障状态:

    if(client.InnerChannel.State != System.ServiceModel.CommunicationState.Faulted) { // call service - everything's fine } else { // channel faulted - re-create your client and then try again } 

    如果是这样,你所能做的就是处置它,重新创build客户端代理,然后再试一次

为了防止服务器陷入故障状态,您必须确保没有发生未处理的exception。 如果WCF发现意外的exception,则不会接受更多的调用 – 安全第一。
避免这种行为的两种可能性:

  1. 使用FaultException(这个对于WCF来说并不是意外的,所以WCF知道服务器仍然有一个有效的状态)
    代替

     throw new Exception("Error xy in my function") 

    总是使用

     throw new FaultException("Error xy in my function") 

    也许你可以尝试……捕获整个块,并在exception的所有情况下抛出一个FaultException

     try { ... some code here } catch (Exception ex) { throw new FaultException(ex.Message) } 
  2. 告诉WCF使用Errorhandler处理所有exception。 这可以通过几种方法来完成,我select了一个简单的属性:
    我们所要做的更多的事情就是在所需的服务实现上使用属性[SvcErrorHandlerBehaviour]

     using System; using System.Collections.ObjectModel; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; namespace MainService.Services { /// <summary> /// Provides FaultExceptions for all Methods Calls of a Service that fails with an Exception /// </summary> public class SvcErrorHandlerBehaviourAttribute : Attribute, IServiceBehavior { public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } //implementation not needed public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } //implementation not needed public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (ChannelDispatcherBase chanDispBase in serviceHostBase.ChannelDispatchers) { ChannelDispatcher channelDispatcher = chanDispBase as ChannelDispatcher; if (channelDispatcher == null) continue; channelDispatcher.ErrorHandlers.Add(new SvcErrorHandler()); } } } public class SvcErrorHandler: IErrorHandler { public bool HandleError(Exception error) { //You can log th message if you want. return true; } public void ProvideFault(Exception error, MessageVersion version, ref Message msg) { if (error is FaultException) return; FaultException faultException = new FaultException(error.Message); MessageFault messageFault = faultException.CreateMessageFault(); msg = Message.CreateMessage(version, messageFault, faultException.Action); } } } 

这是一个简单的例子,通过不使用裸FaultException ,可以深入到IErrorhandler中,但是一个FaultException<>types提供了额外的信息,参见IErrorHandler的详细例子。

附加到faulted事件 ,找出错误发生的原因和时间。

编辑:这也是有帮助的,如果你发布了一些关于你在做什么的更多信息。

事实上,如果在marc_s的build议之后没有成功,请记住,服务器上的web.config中的服务器绑定configuration(或缺lessconfiguration)中的<security>元素可能会导致此exception。 例如,服务器期望Message级安全性,并将客户端configuration为None (或者,如果服务器不是Active Directory域的一部分,但远程客户端主机是)。

提示:在这种情况下,客户端应用程序很可能会在RDP会话中的pipe理帐户下直接在服务器计算机上执行时调用Web服务。

我有一个Web客户端,通过WCF连接到Windows服务。 我的networking应用程序抛出相同的错误

通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它处于Faulted状态,我启用了WCF跟踪,这没什么帮助。 终于重新启动Windows服务解决了它,我仍然不知道的原因。 所以故障排除应该始终从简单的开始。 这是一个例子。 如果有人有类似的问题,请尝试重新启动服务。

我还有一个问题,我不认为其他答案中已经提到过。

我必须在相同的TCP地址和端口上服务端点。 在app.config中,我忘了添加两个端点,所以服务在正确的端口上运行,但是服务接口错误。

如果您在Visual Studio中看到此消息并且解决scheme包含WCF项目。 然后打开此WCF项目设置 – >转到“WCF选项”选项卡 – >“closures”debugging时启动WCF服务主机…“选项

要诊断此问题,请在Visual Studiodebugging器下运行该服务。 使用菜单:debugging|例外,并指出你想抛出exception时中断。

抛出的原始exception比“..它处于故障状态”的错误信息要好得多。

例如,我从ServiceHost.Open()获取这个exception,但是当我在引发时捕获到原始exception时,错误消息是:

服务'MyServiceName'具有零个应用程序(非基础设施)端点。 这可能是因为没有为您的应用程序findconfiguration文件,或者是因为在configuration文件中找不到匹配服务名称的服务元素,或者是因为服务元素中没有定义端点。

修复App.config中的拼写错误解决了这个问题。

不是这个问题的解决scheme,但是如果您遇到Ektron eSync的上述错误,可能是您的数据库磁盘空间不足。

编辑:其实这不完全是一个Ektron eSync唯一的问题。 这可能发生在任何查询完整数据库的服务上。

编辑:磁盘空间不足或阻止访问您需要的目录将导致此问题。