为什么我的ChannelFactory看不到我的端点configuration?

我一直在跟随米格尔·卡斯特罗在WCF 这里的优秀文章,它的工作很好,除了我有以下代码

public AdminClient() { ChannelFactory<IProductAdmin> factory = new ChannelFactory<IProductAdmin>(); productAdminChannel = factory.CreateChannel(); } 

在我的app.config文件中,我有以下configuration:

 <system.serviceModel> <client> <endpoint address="net.tcp://localhost:8002/ProductBrowser" binding="netTcpBinding" contract="Contracts.IProductAdmin" /> </client> </system.serviceModel> 

但是,当我运行AdminClient的构造函数时,我得到一个exception,说没有定义端点。 但是,如果我改变我的configuration,给端点一个名称,然后创build工厂如下,它的工作原理。

 public AdminClient() { var fac = new ChannelFactory<IProductAdmin>("admin"); productAdminChannel = fac.CreateChannel(); } 

 <system.serviceModel> <client> <endpoint name="admin" address="net.tcp://localhost:8002/ProductBrowser" binding="netTcpBinding" contract="Contracts.IProductAdmin" /> </client> </system.serviceModel> 

我很想为此解释。 在MSDN中的文档没有太大的帮助…

使用“*”来使用第一个合格终点。

 public AdminClient() { ChannelFactory<IProductAdmin> factory = new ChannelFactory<IProductAdmin>("*"); productAdminChannel = factory.CreateChannel(); } 

MSDN示例

您需要指定端点名称,因为您可以拥有许多相同types合同的端点。 (例如一个服务被部署在一个TCP和一个http ws端点上)。 微软当然可以在WCF中构build一些东西来检查是否只有一个客户端为合同接口指定,但是这不会是非常一致的。 (如果只有一个为合同指定的端点,它将起作用)。 之后当您为同一合同添加另一个端点时,代码会在这种情况下中断。

这一直在困扰我几天,所以我通过上面链接的文章中显示的示例。 一切工作正常,除了你有问题的第二个客户端代理示例。 正如你所提到的,其他应答者以这种方式创build一个代理需要一个端点名称,将其与客户端(定义端点的地方)相连接。 我仍然不确定为什么它的行为如此,但是我没有明确地将代理连接到端点的情况下使用这个例子。

另一方面,显示如何创build代理的第一个示例不需要显式耦合端点地址或绑定:

  using System; using System.ServiceModel; namespace CoDeMagazine.ServiceArticle { public class ProductClient : ClientBase<IProductBrowser>, IProductBrowser { #region IProductBrowser Members public ProductData GetProduct( Guid productID) { return Channel.GetProduct(productID); } public ProductData[] GetAllProducts() { return Channel.GetAllProducts(); } public ProductData[] FindProducts( string productNameWildcard) { return Channel.FindProducts( productNameWildcard); } #endregion } } 

这似乎工作得很好。 所以,也许第二个代理例子只是一个糟糕的做事方式,或者我们错过了一些明显的东西…

您可以离开,而无需在服务端指定端点名称。 对于客户端,您需要指定名称,因为您可能正在连接到具有相同合同的多个服务。 WCF如何知道你想要哪一个?

如果您不想指定端点名称明确性,则可以这样写:

  public AdminClient() { ChannelFactory<IProductAdmin> factory = new ChannelFactory<IProductAdmin>(string.Empty); productAdminChannel = factory.CreateChannel(); } 

无需构造函数无参数是行不通的。