c# - 由于 Service 的 'FaultedState',WCF.ServiceChannel 无法通信

标签 c# wcf service

我正在创建一个自托管的 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);
}

异常(exception):
The communication object, "System.ServiceModel.Channels.ServiceChannel",
cannot be used for communication because it is in the Faulted state.

I never enter SelfHost_Faulted nor are there any Exceptions on my Service



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

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

最佳答案

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

如果你改变

channel?.SetState("Test");


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

您将看到 2 条消息:

There was no endpoint listening at http://localhost:8000/ServiceModelSamples/Service that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.





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



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

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

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

问题将得到解决。

关于c# - 由于 Service 的 'FaultedState',WCF.ServiceChannel 无法通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42588452/

相关文章:

c# - 在 Kestrel、helios、WebListener 和单独的控制台进程中托管 Asp.Net vNext 应用程序有何不同?

.net - 此消息无法支持操作,因为它已被复制

android - 如何从服务类中更改墙纸?

linux - 在停用另一个服务之前激活并运行 oneshot 服务

c# - 如何将运行时方法传递给自定义属性或可行的替代方法

c# - 从接口(interface)继承的方法可以返回接口(interface)中的另一种类型吗?

c# - WPF 数据网格 : modify all selected items

c# - 如何隐藏我的 WCF 服务

wcf - 413 Request Entity Too Large in wcf 服务上传大图片文件时

android - 在 React Native 上设置 Android BroadcastReceiver