为什么“在配置元素集合中找不到与该键匹配的元素”?

4
我正在以编程方式创建一个命名管道WCF服务和客户端。
服务代码执行以下操作:
serviceHost = new ServiceHost(typeof(CFCAccessPointService), new Uri(Names.Address));
serviceHost.AddServiceEndpoint(typeof (ICfcAccessPoint), new NetNamedPipeBinding(Names.Binding), Names.Contract);
serviceHost.Open();

客户端代码:
var ctx = new InstanceContext(new StatusHandler());
s_proxy = new DuplexChannelFactory<ICfcAccessPoint>(ctx, new NetNamedPipeBinding(Names.Binding), new EndpointAddress(Names.Address));

带有、具有、伴随着。
public static class Names
{
    public const string Address = "net.pipe://localhost/CFC/Plugins/GuestAccessService";
    public const string Binding = "netNamedPipeBinding_ICfcAccessPoint";
    public const string Contract = "GuestAccessClientServerInterface.ICfcAccessPoint";
}

为了确保客户端和服务保持不变。但是,如果我删除Names.Binding,这样就没有指定绑定配置了,那么我会收到错误消息,提示在端点上找不到侦听器。如果我包括它,我会得到“在配置元素集合中找不到匹配键的元素”的错误消息......我没有使用.config文件。还缺少什么?
2个回答

3
绑定是好的,无论如何都不需要参数。实际上,没有任何问题。
问题在于合同。当我改变代码为:
public static class Names
{
    public const string Address = "net.pipe://localhost/CFC/Plugins/GuestAccessService/";
    public const string Binding = "";
    public const string Contract = "CfcAccessPoint";
}

在服务端方面:

this.serviceHost.AddServiceEndpoint(typeof(ICfcAccessPoint), new NetNamedPipeBinding(), Names.Contract);

在客户端方面:
var ctx = new InstanceContext(this);
proxy = new DuplexChannelFactory<ICfcAccessPoint>(ctx, new NetNamedPipeBinding(), new EndpointAddress(Names.Address) + Names.Contract);

然后一切正常。该服务只命名管道;客户端将地址添加到管道名称中。

看,多么简单!


1
这意味着您的配置文件中没有该名称的绑定。既然您已经声明不使用配置文件,那么这并不奇怪。是否有原因导致您无法在web.config或app.config中配置WCF端点?这只是我的观点,但我发现当我需要随机调整服务的各个属性时,配置方法更加灵活。
无论如何,在MSDN文档中,NetNamedPipeBinding(string)构造函数的签名如下:
public NetNamedPipeBinding(
    string configurationName
)

这意味着,使用此构造函数实例化 NetNamedPipeBinding 的唯一方式是需要在您的 web.config 或 app.config 文件中存在一个名称匹配该字符串的绑定。类似于以下内容:
<system.serviceModel>
    <bindings>
        <netNamedPipeBinding>
            <binding name="netNamedPipeBinding_ICfcAccessPoint" />
        <netNamedPipeBinding>
    </bindings>
</system.serviceModel>

您可能正在寻找更像这样的构造函数:
public NetNamedPipeBinding(
    NetNamedPipeSecurityMode securityMode
)

这里是MSDN链接。

使用这个构造函数,你的服务主机代码会更像这样:

serviceHost = new ServiceHost(typeof(CFCAccessPointService), new Uri(Names.Address));
serviceHost.AddServiceEndpoint(typeof (ICfcAccessPoint), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), Names.Contract);
serviceHost.Open();

而你的客户端代码如下:

var ctx = new InstanceContext(new StatusHandler());
s_proxy = new DuplexChannelFactory<ICfcAccessPoint>(ctx, new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress(Names.Address));

这样可以避免使用配置文件。

抱歉,但是这两个建议都没有起作用。当我修改代码以设置安全模式时,我得到了“无监听器”错误。添加配置文件毫无影响。 - shipr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接