周转基金。由于服务'FaultedState',服务通道无法通信



我正在创建一个自我主持的WCF Service

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface IStateChecker
{
    [OperationContract]
    void SetState(string state);
}

这是我的Service

public class StateCheckerService : IStateChecker
{
    public void SetState(string state)
    {
        Console.WriteLine($"{DateTime.Now.ToString("dd.MM.yyyy HH:mm:sss")} : {state}");
    }
}

这是我的实现:

//Define baseaddres:
Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");
//create host:
ServiceHost selfHost = new ServiceHost(typeof(StateCheckerService), baseAddress);
try
{
     //Add endpoint to host:
     selfHost.AddServiceEndpoint(typeof(IStateChecker), new WSHttpBinding(), "StateCheckerService");
     //Add metadata exchange:
     ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
     smb.HttpGetEnabled = true;
     selfHost.Description.Behaviors.Add(smb);

     selfHost.Faulted += SelfHost_Faulted;
     //Start service
     selfHost.Open();
     Console.WriteLine("Starting Service...");
     if (selfHost.State == CommunicationState.Opened)
     {
         Console.WriteLine("The service is ready.");
     }
     Console.WriteLine("Press <ENTER> to terminate service.");
     Console.ReadLine();
     //Shutdown service
     selfHost.Close();
}
catch (CommunicationException ce)
{
    Console.WriteLine("An exception occurred: {0}", ce.Message);
    selfHost.Abort();
}
private static void SelfHost_Faulted(object sender, EventArgs e)
{
    ServiceHost host = sender as ServiceHost;
    Console.WriteLine(host?.State);
    Console.WriteLine(e?.ToString());
    host?.Open();
}

现在,当涉及客户端时,我会出现错误。

try
{
    //Works using the ServiceReference (wsdl ... created by VisualStudio):
    using (StateCheckerServiceReference.StateCheckerClient client = new StateCheckerClient())
    {
        client.SetState("Test");
    }
    //Does not work:
    EndpointAddress endpointAddress = new EndpointAddress("http://localhost:8000/ServiceModelSamples/Service");
    using (ChannelFactory<IStateCheckerChannel> factory = new ChannelFactory<IStateCheckerChannel>("WSHttpBinding_IStateChecker", endpointAddress))
    {
        using (IStateCheckerChannel channel = factory.CreateChannel(endpointAddress))
        {
            channel?.SetState("Test");
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

例外:

The communication object, "System.ServiceModel.Channels.ServiceChannel",
cannot be used for communication because it is in the Faulted state.

我从不输入SelfHost_Faulted,我的服务上也没有任何Exception s

我这样做是因为我想更改客户端应在运行时连接的Endpoint

如果我做错了,请告诉我。否则,对我的代码有问题的任何提示将受到高度赞赏。

这个问题非常微不足道,但被WCF基础架构隐藏(奇怪的是标准模式的实现)。

如果您更改

channel?.SetState("Test");

to

try
{
    channel?.SetState("Test");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

您会看到2条消息:

在http://localhost:8000/serviceModelSamples/服务中没有端点侦听。这通常是由不正确的地址或肥皂作用引起的。有关更多详细信息,请参见Innerexception(如果存在)。

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

第一个是真正的例外(类型EndpointNotFoundException),由内部catch捕获。

第二个(误导)例外是类型CommunicationObjectFaultedException,并由channel.Dispose()(?!)在using块的末端拨打,因此隐藏了原始的块。WCF实施根本不遵循Dispose()不应该投掷的规则!

话虽如此,问题在您的客户端。根据服务配置,该配置应为"baseAddress/StateCheckerService",而目前仅是"baseAddress"。因此,只需使用正确的端点地址
var endpointAddress = new EndpointAddress(
    "http://localhost:8000/ServiceModelSamples/Service/StateCheckerService");

将解决问题。

最新更新