我正在创建一个自托管的 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 anyException
s 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/