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

时间:2015-05-05 23:01:27

标签: c# wcf-binding

我正在以编程方式创建命名管道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 个答案:

答案 0 :(得分:1)

这意味着配置文件中没有与该名称绑定。由于您已声明您没有使用配置文件,因此这并不奇怪。是否有理由在web.config或app.config中配置WCF端点?这只是我的观点,但是当我需要对我的服务的各个属性进行随机调整时,我发现配置方法更加灵活。

无论哪种方式,NetNamedPipeBinding(string)构造函数的MSDN docs,签名如下所示:

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));

这应该避免需要配置文件。

答案 1 :(得分:1)

无论哪种方式,绑定都很好,实际上根本不需要参数。

麻烦在于合同。当我改为代码:

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);
然后事情很好。该服务只是命名管道;客户端将地址添加到管道名称。

瞧!