由于服务的"FaultedState",WCF.ServiceChannel无法通信

Fel*_* D. 2 c# service wcf

我正在创建一个自我主题WCF Service.

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

这是我的Service:

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

这是我的实施:

//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();
}
Run Code Online (Sandbox Code Playgroud)

现在,当涉及到客户端时,我得到一个错误.

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);
}
Run Code Online (Sandbox Code Playgroud)

例外:

The communication object, "System.ServiceModel.Channels.ServiceChannel",
cannot be used for communication because it is in the Faulted state.
Run Code Online (Sandbox Code Playgroud)

我从不进入,SelfHost_Faulted也没有任何Exception关于我的服务

我这样做是因为我想改变Endpoint客户端应该在运行时连接到.

如果我做错了请告诉我.否则,我的代码的任何提示都会受到高度赞赏.

Iva*_*oev 5

这个问题非常简单,但是被WCF基础设施所隐藏(标准模式的奇怪实现).

如果你改变了

channel?.SetState("Test");
Run Code Online (Sandbox Code Playgroud)

try
{
    channel?.SetState("Test");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}
Run Code Online (Sandbox Code Playgroud)

你会看到2条消息:

http:// localhost:8000/ServiceModelSamples/Service上没有可以接受该消息的端点.这通常是由错误的地址或SOAP操作引起的.有关更多详细信息,请参阅InnerException(如果存在).

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

第一个是EndpointNotFoundException内部捕获的真实异常(类型)catch.

第二个(误导性)异常是类型的,CommunicationObjectFaultedException并且channel.Dispose()using块的末尾调用(?!)抛出,因此隐藏了原始异常.WCF实现根本不遵循Dispose()不应抛出的规则!

话虽如此,问题出在您的客户端端点.根据服务配置,它应该是"baseAddress/StateCheckerService"目前只是"baseAddress".所以只需使用正确的端点地址即可

var endpointAddress = new EndpointAddress(
    "http://localhost:8000/ServiceModelSamples/Service/StateCheckerService");
Run Code Online (Sandbox Code Playgroud)

这个问题将得到解决.