【问题标题】:WCF Metadata contains a reference that cannot be resolvedWCF 元数据包含无法解析的引用
【发布时间】:2019-02-21 21:33:50
【问题描述】:

我花了几个小时搜索这个错误,并且几乎测试了 Google 上的所有内容。

我想在 C# 中使用 TCP、.NET4 和 VS2010 访问服务。

我有一个非常小的服务:


namespace WcfService_using_callbacks_via_tcp
{
    [ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)]
    public interface IService1
    {
        [OperationContract]
        string Test(int value);
    }

    public interface ICallback
    {
        [OperationContract(IsOneWay = true)]
        void ServerToClient(string sms);
    }
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class Service1 : IService1
    {
        public string Test(int value)
        {
            ICallback the_callback = OperationContext.Current.GetCallbackChannel<ICallback>();
            the_callback.ServerToClient("Callback from server, waiting 1s to return value.");
            Thread.Sleep(1000);
            return string.Format("You entered: {0}", value);
        }

    }
}

有了这个 Web.config:


<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="WcfService_using_callbacks_via_tcp.Service1" behaviorConfiguration="Behaviour_Service1">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:5050/Service1" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="DuplexNetTcpBinding_IService1" contract="WcfService_using_callbacks_via_tcp.IService1"/>
        <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="mexTcp" contract="IMetadataExchange"/>
      </service>
    </services>

    <bindings>
      <!--
        TCP Binding
      -->
      <netTcpBinding>
        <binding name="DuplexNetTcpBinding_IService1" sendTimeout="00:00:01"
                 portSharingEnabled="true">

        </binding>

        <binding name="mexTcp" portSharingEnabled="true">
          <security mode="None" />
        </binding>
      </netTcpBinding>


    </bindings>

    <behaviors>
      <serviceBehaviors>
        <!--
          Behaviour to avoid a rush of clients and to expose metadata over tcp
        -->
        <behavior name="Behaviour_Service1">
          <serviceThrottling maxConcurrentSessions="10000"/>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>

        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

这个代码来托管它:


static void Main(string[] args)
{
    Uri base_address = new Uri("net.tcp://localhost:5050/Service1");
    ServiceHost host = null;
    try
    {
        // Create the server
        host = new ServiceHost(typeof(Service1), base_address);
        // Start the server
        host.Open();
        // Notify it
        Console.WriteLine("The service is ready at {0}", base_address);
        // Allow close the server
        Console.WriteLine("Press <Enter> to stop the service.");
        Console.ReadLine();
        // Close it
        host.Close();
    }
    catch (Exception ex)
    {
        // Opus an error occurred
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine(string.Format("Host error:\r\n{0}:\r\n{1}", ex.GetType(), ex.Message));
        Console.ReadLine();
    }finally
    {
        // Correct memory clean
        if(host != null)
            ((IDisposable)host).Dispose();
    }
}

现在我想创建客户端,但它是不可能的。我已经直接使用了 Add Service Reference 和 svcutil,但是我收到了这个错误:


C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>svcutil.exe net.tcp://loc alhost:5050/Service1 Microsoft (R) 服务模型 元数据工具 [Microsoft (R) Windows (R) Communication Foundation, 版本 4.0.30319.1] 版权所有 (c) Microsoft Corporation。所有权利 保留。

尝试从以下位置下载元数据 'net.tcp://localhost:5050/Service1' 使用 W S 元数据交换。这个 URL 不支持 DISCO。 Microsoft (R) 服务模型元数据工具 [Microsoft (R) Windows (R) Communication Foundation,版本 4.0.30319.1] 版权所有 (c) Microsoft Corporation。保留所有权利。

错误:无法从 net.tcp://localhost:5050/Service1 获取元数据

如果这是您使用的 Windows (R) Communication Foundation 服务 可以访问 ss,请检查您是否启用了元数据发布 在指定的地址。如需帮助启用元数据发布, 请参阅 MSDN 文档 http://go.microsoft.com/fwlink/?LinkId=65455.

WS-元数据交换错误 URI:net.tcp://localhost:5050/Service1

元数据包含无法解析的引用:'net.tcp://localhost:5050/Service1'。

套接字连接被中止。这可能是由于处理您的消息时出错或接收超时超出 远程主机或底层网络资源问题。当地的 套接字超时为“00:04:59.9863281”。

Se ha forzado la interruptción de una conexión existente por el host remoto

如果您需要更多帮助,请输入“svcutil /?”


所以,我可以毫无问题地托管服务,但我无法创建代理。

我已经尝试了几乎所有找到的配置,但我认为当前的 web.config 是正确的。端点使用了使用 mex 的行为、安全性和绑定。

我尝试创建一个 app.config 并将其设置为与 svcutil.exe 相同的文件夹。

【问题讨论】:

  • @JohnSaunders,我无法理解为什么像你这样的人会将答案代码复制到问题代码中,从而使整个问题完全无效。我只是浪费时间试图找出问题代码和答案代码之间的区别,然后才意识到有人做了你所做的事情......这样做有什么好处?没有人知道真正的问题是什么。
  • @Sheridan:这是一个重要的生活提示:每当你发现自己在说“我不明白怎么做”或“我不明白怎么做”之类的话时,考虑一下这可能是一个你的理解或愿景的问题。您“无法理解”,因为我没有这样做。我只是缩进了代码。仔细查看编辑历史。我刚做了。
  • 确实仔细查看了之前我的评论,虽然我接受你的评论,但我想说它仍然出现 就好像您添加了该代码...啊...这只是在 Side by Side 视图中。在其他视图中,我可以看到真实的画面。抱歉...在发表评论之前我应该​​仔细看看。

标签: wcf tcp binding metadata


【解决方案1】:

您缺少服务配置

<system.serviceModel>
  <services>
    <service name="WcfService_using_callbacks_via_tcp.Service1" 
      behaviorConfiguration="Behavior_Service1">
      <host>
        <baseAddresses>
          <add baseAddress="net.tcp://localhost:5050/Service1" />
        </baseAddresses>
      </host>
      <endpoint address="" contract="WcfService_using_callbacks_via_tcp.IService1"
         binding="netTcpBinding" bindingConfiguration="DuplexNetTcpBinding_IService1" />
      <endpoint address="mex" contract="IMetadataExchange" binding="mexTcpBindng" />
    </service>
  </services>
  ...
</system.serviceModel>

有了这个配置,你应该不需要在代码中定义基地址了。

【讨论】:

  • 感谢您的回复。我没有在服务器的控制台项目上正确设置 app.config。我已经在 host.Open(); 之前在代码中声明了绑定和行为;它奏效了。
  • 如果这解决了您的问题,请不要忘记标记为答案
【解决方案2】:

我在尝试更新现有服务引用时收到了同样的错误。事实证明,我在同一个命名空间中有同名的数据合约。进一步调查发现了真正的错误:

类型 [redacted] 的 DataContract 无法添加到 DataContractSet,因为类型“[redacted]”在命名空间“”中具有相同的数据合同名称“DocumentInfo” [已编辑]' 已经存在,并且合同不等效。

我更改了 DataContract 以提供其中一个类的名称。

[DataContract(Namespace = "urn:*[redacted]*:DataContracts", Name = "SC_DocumentInfo")]

我在此处发布此内容,以防它可能对遇到相同问题的人有所帮助。

【讨论】:

  • 我很确定这是我的问题,因为我更改了几个数据合同。我想知道你做了什么来获得提到的消息,该消息将有助于找出哪个 DataContract 已经存在
  • @HaraldCoppoolse 我试图在浏览器中查看服务,但那里出现了更详细的错误。我正在使用 VS 2015,导航到该服务,右键单击它并选择在浏览器中查看。希望对你有帮助!
【解决方案3】:

我收到了同样的错误消息,事实证明,问题是由于 cmets 块中的文本引起的

<!-- comments included characters like à, ç and ã -->

从注释块中删除这些字符后,一切正常

【讨论】:

    【解决方案4】:

    也许它会对某人有所帮助。

    我的问题在于合同争论,我在 Event Viewer 的帮助下发现了它:

    操作 [方法名称] 要么具有参数,要么具有使用 MessageContractAttribute 属性的返回类型。为了使用消息契约来表示请求消息,操作必须有一个单个参数,并带有 MessageContractAttribute。为了使用 Message Contract 表示响应消息,操作的返回值必须是使用 MessageContractAttribute 属性的类型,并且操作可能没有任何 out 或 ref 参数。

    因此,如果您附加了多个参数,并且已经具有 [MessageContract] 参数,那么您将看到有问题的错误。完全不明显。

    【讨论】:

      【解决方案5】:

      我在仅使用 tcp 绑定时遇到了同样的问题(当客户端没有在“添加服务引用”菜单中“看到”服务时)。在尝试添加行为后,我的服务以异常结束,因为它没有找到正确的地址。 我不知道这是否是最好的主意,但是您可以将第二个基地址添加为 http.... 这是我的配置和代码,它可以工作。

          <?xml version="1.0" encoding="utf-8" ?><configuration>  <system.serviceModel>  <services>
        <service name="TestBindings.StockQuoteService">
          <host>
            <baseAddresses>
              <add baseAddress="net.tcp://10.62.60.62:34000/StockQuoteService" />
              <add baseAddress ="http://10.62.60.62:12000/StockQuoteService"/>
            </baseAddresses>
          </host>
          <endpoint address=""
          contract="TestBindings.IStockQuoteService"
          binding="netTcpBinding" />
        </service>
      </services>
      

      还有代码

        class Program
      {
          static void Main(string[] args)
          {
              ServiceHost sh = new ServiceHost(typeof(StockQuoteService));
              ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
              behavior.HttpGetEnabled = true;
              sh.Description.Behaviors.Add(behavior);
              sh.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(),
                  "mex");
              sh.Open();
      

      现在客户端使用http地址添加服务引用,客户端自动生成config使用net.tcp协议调用该函数。

      【讨论】:

      • 这似乎是一个不错的解决方案,而且它看起来很符合逻辑,但是一旦你的客户端生成了,你需要http地址吗?
      • 如果您有一个客户端,则不需要http地址。但是如果你以后可能需要生成一些客户端,最好把它放在配置中。
      【解决方案6】:

      对于上述问题,请检查添加引用时生成的 reference.svc 文件。其中提到的 url 将用于更新服务,以便您检查该服务是否正在运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多