通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它处于Faulted状态.
什么是这个错误,我将如何解决它?
mar*_*c_s 137
您收到此错误是因为您在服务器端发生了.NET异常,并且您没有捕获并处理它,也没有将其转换为SOAP错误.
现在,由于服务器端"被轰炸",WCF运行时已"故障"通道 - 例如客户端和服务器之间的通信链路无法使用 - 毕竟,它看起来像你的服务器刚刚爆炸,所以你无法与之通信它了.
所以你需要做的是:
始终捕获并处理服务器端错误 - 不要让.NET异常从服务器传递到客户端 - 始终将这些错误包装成可互操作的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
}
如果是,您所能做的只是处理它并再次重新创建客户端代理,然后再试一次
Ber*_*ndK 29
要防止服务器陷入故障状态,您必须确保不会引发未处理的异常.如果WCF看到意外的异常,则不再接受任何呼叫 - 安全第一.
避免这种行为的两种可能性:  
使用FaultException(这对于WCF来说并不意外,因此WCF知道服务器仍然具有有效状态)
而不是  
throw new Exception("Error xy in my function")  
永远使用
throw new FaultException("Error xy in my function")  
也许你可以尝试..捕获整个块并在异常的所有情况下抛出FaultException
try   
{  
    ... some code here   
}
catch (Exception ex)
{  
    throw new FaultException(ex.Message)   
}
告诉WCF使用Errorhandler处理所有异常.这可以通过多种方式完成,我选择了一个使用属性的简单方法:
我们必须做的更多,就是[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);
        }
    }
}
这是一个简单的例子,您可以通过不使用裸体来深入了解IErrorhandler FaultException,但是FaultException<>提供额外信息的类型请参阅IErrorHandler以获取详细示例.
事实上,如果在遵循marc_s的建议后不成功,请记住服务器上web.config中服务器绑定配置(或缺少)中的<security>元素可能会导致此异常.例如,服务器期望Message-level安全性,客户端配置为None(或者,如果服务器不是Active Directory域的一部分,但远程客户端主机是).
提示:在这种情况下,客户端应用程序很可能在RDP会话中的管理帐户下直接在服务器计算机上执行时调用Web服务.