找不到默认的端点元素

389

我已经将代理添加到了一个VS2008/.NET 3.5解决方案中的WebService。在构建客户端时,.NET会抛出以下错误:

无法在ServiceModel客户端配置部分中找到引用“IMySOAPWebService”合同的默认终结点元素。这可能是因为没有为应用程序找到配置文件,或者因为在客户端元素中找不到与此合同匹配的终结点元素。

搜索这个错误告诉我在合同中使用完整的命名空间。这是我的app.config文件完整的命名空间:

<client>
  <endpoint address="http://192.168.100.87:7001/soap/IMySOAPWebService"
            binding="basicHttpBinding" bindingConfiguration="IMySOAPWebServicebinding"
            contract="Fusion.DataExchange.Workflows.IMySOAPWebService" name="IMySOAPWebServicePort" />
</client>

我在本地运行XP(之所以提到这一点是因为许多Google搜索结果提到win2k3)app.config已复制到app.exe.config,因此这不是问题的原因。

有什么线索吗?


如果这是在 Web 服务器上运行,那么你需要添加 .svc。例如:"http://192.168.100.87:7001/soap/IMySOAPWebService.svc"。 - Darren C
该服务不是一个.NET服务,也没有在Web服务器上运行。 - edosoft
我在使用.NET开发的项目中解决了这个问题,但是我有一些VB6项目也遇到了同样的问题。有什么想法吗? - Gabriel Intriago
35个回答

623

如果您在类库中调用服务并从另一个项目中调用该类库,则可能会出现此错误。

在这种情况下,您需要将WS配置设置包含到主项目的app.config(如果是winapp)或web.config(如果是web应用程序)中。即使使用PRISM和WPF / Silverlight,也应该采用这种方法。


10
有没有自动合并这两个的方法?如果类库更新了它的配置,那该怎么办?难道你只能记得在引用它的所有项目中更新复制的配置信息吗?这种修复似乎太过依赖开发人员的警惕性了... - Sean Hanley
2
我在一个WP7应用程序(我相信是Silverlight)中遇到了同样的错误,花费了我太长时间才注意到ServiceReferences.ClientConfig是在项目目录中生成的。将文件中的<bindings><client>元素从我的库复制到我的主应用程序中(之前为空),使事情正常运行。 - David Mason
4
我会尽力完成翻译,请确认以下内容是否正确:据我所知,导致这种情况发生的原因是,配置值从解决方案中的主项目中读取,无论是web、winforms、wpf等。例如,假设您有一个用于访问数据库的类库项目,则connectionString条目需要在主项目配置文件中,而不是类库配置文件中。 - Ciarán Bruen
7
因此,我们可以得出结论,如果在库中使用WCF,最好直接编码设置,就像链接https://dev59.com/t2sz5IYBdhLWcg3wv6ju所示。 - Youngjae
1
我甚至尝试从新项目中添加对服务的引用,但是我得到了相同的错误。 - Saher Ahwal
显示剩余4条评论

102

我通过自己创建绑定和终结点地址实例来解决这个问题(我认为其他人可能已经建议过),因为我不想向配置文件中添加新的设置(这是一些现有库代码的替代品,被广泛使用,并且之前使用较旧的Web服务引用等),因此我希望能够将其放置在那里而无需在各处添加新的配置设置。

var remoteAddress = new System.ServiceModel.EndpointAddress(_webServiceUrl);

using (var productService = new ProductClient(new System.ServiceModel.BasicHttpBinding(), remoteAddress))
{
    //set timeout
    productService.Endpoint.Binding.SendTimeout = new TimeSpan(0,0,0,_webServiceTimeout);

    //call web service method
    productResponse = productService.GetProducts();
} 

编辑

如果你正在使用https协议,则需要使用BasicHttpsBinding而不是BasicHttpBinding


1
这是一个有帮助的答案。在我使用的 Web 服务中,自定义端点必须在对象的初始声明中绑定。如果我尝试稍后绑定它,它将无法工作。 - Paul Morel
2
尽管我怀疑排名第一的答案可能也能解决问题,但你的解决方案有效,并且对我来说似乎更可取,因为我不想自己拼凑配置文件。 - Sam I am says Reinstate Monica
运行得非常好!我更喜欢能够在代码中设置终结点,而不是分发一个带有我的应用程序的“app.config”文件。 - Daniel Gee
2
如果它是一个Https Web服务,请记得将BasicHttpBinding()更改为BasicHttpsBinding()。 - Anthony
很好的回答。我想创建一个代理API,使用Web API 2解决方案,但不想在Web.Config中放置任何内容,这个答案让我能够保持通信接近实际服务方法。干得好! - Trevor
显示剩余2条评论

83

经过多次尝试,我最终通过使用

contract="IMySOAPWebService"

来解决问题,即在配置文件中不使用完整的命名空间。由于某些原因,完整名称未能正确解析。


4
看起来合同名称必须与客户端完全相同。在我的情况下,我使用了var proxy = new ExternalServices.ServiceClient("MyServiceEndpoint");,当我将命名空间添加到合同中时,它就起作用了:contract="ExternalServices.IMyService" - Anatoly Mironov
这对我没用。我的问题可能有点不同。我有时会遇到这个错误,而不是总是出现。可能是什么问题呢?错误可能在服务端吗?_谢谢 - albatross

61

我曾经遇到了同样的问题。原来在web引用中,你必须将URL作为构造函数的第一个参数提供:

new WebService.WebServiceSoapClient("http://myservice.com/moo.aspx");

对于一种新的风格的Web服务引用,您必须提供一个名称,该名称指向配置中的端点条目:

new WebService.WebServiceSoapClient("WebServiceEndpoint");

Web.configApp.config中有相应的条目:

<client>
      <endpoint address="http://myservice.com/moo.aspx"
        binding="basicHttpBinding" 
        bindingConfiguration="WebService"
        contract="WebService.WebServiceSoap"
        name="WebServiceEndpoint" />
    </client>
  </system.serviceModel>

要移除关于“在旧程序中可行”的局限性非常困难...


3
啊哈!这对我有帮助,以前我一直在使用空构造函数,但是它一直失败:new WebService.WebServiceSoapClient(); // 失败 - travis
这个解决方案确实起作用了!!!但是,我真的很好奇为什么默认的终端点没有加载?有什么想法可以解释原因吗? - Dipti Mehta
@Andomar 抱歉又把旧帖子搬出来。WebReference 和 ServiceReference 有什么区别呢?我觉得前者更方便一些,但是 ServiceReference 是新酷炫东西吧... - Kev

18
“如果您在类库中调用服务并从另一个项目调用该类库,则可能会出现此错误。”
“在这种情况下,如果是winapp或web app,则需要将WS配置设置包含在主项目的app.config或web.config中。即使使用PRISM和WPF / Silverlight也是如此。”
“但是,如果您无法更改主项目(例如Orchard CMS),则可以将WCF服务配置保留在您的项目中。”
“您需要创建一个带有客户端生成方法的服务助手:”
public static class ServiceClientHelper
{
    public static T GetClient<T>(string moduleName) where T : IClientChannel
    {
        var channelType = typeof(T);
        var contractType = channelType.GetInterfaces().First(i => i.Namespace == channelType.Namespace);
        var contractAttribute = contractType.GetCustomAttributes(typeof(ServiceContractAttribute), false).First() as ServiceContractAttribute;

        if (contractAttribute == null)
            throw new Exception("contractAttribute not configured");

        //path to your lib app.config (mark as "Copy Always" in properties)
        var configPath = HostingEnvironment.MapPath(String.Format("~/Modules/{0}/bin/{0}.dll.config", moduleName)); 

        var configuration = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = configPath }, ConfigurationUserLevel.None);
        var serviceModelSectionGroup = ServiceModelSectionGroup.GetSectionGroup(configuration);

        if (serviceModelSectionGroup == null)
            throw new Exception("serviceModelSectionGroup not configured");

        var endpoint = serviceModelSectionGroup.Client.Endpoints.OfType<ChannelEndpointElement>().First(e => e.Contract == contractAttribute.ConfigurationName);
        var channelFactory = new ConfigurationChannelFactory<T>(endpoint.Name, configuration, null);
        var client = channelFactory.CreateChannel();
        return client;
    }
}

并且使用它:

using (var client = ServiceClientHelper.GetClient<IDefaultNameServiceChannel>(yourLibName)) {
                ... get data from service ...
            }

详细情况请参见此文章


18

我遇到了这样的问题,其中我有:

  • 某处托管的WCF服务
  • 主项目
  • 类型为“类库”的使用服务引用WCF服务的消费者项目
  • 主项目从消费者项目调用方法

现在消费者项目在我的 app.config 的 <system.serviceModel> 标签中拥有所有相关的配置设置,但它仍然抛出与上述相同的错误。

我所做的就是将相同的标签 <system.serviceModel> 添加到我的主项目的 app.config 文件中,最后我们终于成功了。

实际问题,就我而言,是它读取了错误的配置文件。它不是指向消费者的 app.config,而是指向主项目的配置。我花了两个小时才找出来。


1
相同。在您的库中搜索<system.serviceModel>,然后将其复制到主应用程序的app.config中。这只是类库app.config在运行时未被读取的另一个症状。我花了很多时间来弥补这个疏忽(在我看来)。如果我想让库从它的app.config中读取配置,请让它自己读取。否则,为什么一开始就要为类库创建app.config呢? - SteveCinq
我确实有类似的情况,我的消费者项目的应用配置服务模型部分和主项目的应用配置服务模型是相同的,但仍然出现了这个错误。可能是还有其他原因在我这里引起了这个错误。 - ManojRawat

16

当你遇到一个让人崩溃的错误,比如在类文件中引用服务时的错误,请把服务配置信息复制到你的控制台或Windows应用程序的app.config web.config中。虽然有一些回答提到了正确的解决方案,但是没有一个回答告诉你需要复制什么。下面让我们来纠正一下。

这是我从我的类库配置文件中复制出来的内容,为了解决我编写的名为“TranslationServiceOutbound”的服务的疯狂错误问题,我将它粘贴到了我的控制台应用程序的配置文件中。

你基本上希望复制system.serviceModel部分中的所有内容:

  <system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_ITranslationServiceOutbound" />
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="http://MyHostName/TranslationServiceOutbound/TranslationServiceOutbound.svc"
    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITranslationServiceOutbound"
    contract="TranslationService.ITranslationServiceOutbound" name="BasicHttpBinding_ITranslationServiceOutbound" />
</client>

:这是一个空的HTML段落标签。

16

这令我疯狂。

我正在使用Silverlight 3 Prism (CAB)和WCF。

在调用Prism模块中的WCF服务时,我会遇到如下错误:

在服务模型客户端配置部分中找不到引用协定“IMyService”的默认终结点元素。这可能是因为未找到应用程序的配置文件或未找到与此协定匹配的终结点元素。

事实证明,它在Shell的.xap文件中查找ServiceReferences.ClientConfig文件,而不是模块的ServiceReferences.ClientConfig文件。我将我的终结点和绑定添加到了现有的Silverlight Shell应用程序的ServiceReferences.ClientConfig文件中(它调用自己的WCF服务)。

然后我不得不重新构建Shell应用程序,以生成新的.xap文件,放在我的Web项目的ClientBin文件夹中。

现在,以下代码终于可以工作了:

MyServiceClient myService = new MyServiceClient();

12

在一个ASP.NET应用程序中,我遇到了一个错误,其中WCF服务已添加到类库中,并作为引用的.dll文件添加到了位于bin文件夹中的ASP.NET应用程序中。要解决此错误,需要将引用WCF服务的类库中的app.config文件中的配置设置复制到ASP.NET站点/应用程序的web.config设置中。


虽然其他答案可能描述了相同的问题,但是这个答案描述了我的确切情况,我终于明白了问题所在。谢谢你挽救了我的一天。 - Wouter Vanherck

11

对于消费服务的非库应用程序进行单元测试可能会导致此问题。

其他人输入的信息解决了根本原因。如果你正在尝试编写自动化测试用例,并且你要测试的单元将实际调用服务接口,那么你需要将服务引用添加到测试项目中。这是一种应用程序使用库类型错误的变体。我没有立即意识到这一点,因为我消费接口的代码不在一个库中。但是,当测试实际运行时,它将从测试程序集而不是被测试的程序集中运行。

将服务引用添加到单元测试项目中可以解决我的问题。


是的,这就是正确的方式! - Dan Hessler

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