问题 WCF元数据包含无法解析的引用


我花了几个小时搜索这个错误,我几乎测试了它在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。所有权利   保留。

试图从中下载元数据   使用W S-Metadata Exchange的'net.tcp:// localhost:5050 / Service1'。这个   URL不支持DISCO。 Microsoft(R)服务模型元数据工具   [Microsoft(R)Windows(R)Communication Foundation,Version   4.0.30319.1]版权所有(c)Microsoft Corporation。版权所有。

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

如果这是您的Windows(R)Communication Foundation服务   有加入,请检查您是否已启用元数据发布   在指定的地址。有关启用元数据发布的帮助   请参阅MSDN文档    http://go.microsoft.com/fwlink/?LinkId=65455

WS-Metadata Exchange错误   URI:net.tcp:// localhost:5050 / Service1

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

套接字连接已中止。这可能是由于错误处理您的消息或超出接收超时造成的   远程主机,或者是一个非常规的网络资源问题。本地   套接字超时为'00:04:59.9863281'。

Se ha forzadolaintercucióndeunaconexiónexistentepor el host remoto

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


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

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

我尝试创建app.config并使用svcutil.exe将其设置为同一文件夹。


2228
2018-01-11 17:22


起源

@JohnSaunders,我无法理解为什么有声誉的人会将答案代码复制到问题代码中,从而完全使整个问题无效。在我意识到有人做了你做过的事情之前,我只是浪费时间试图找出问题代码和答案代码之间的区别......这样做有什么好处?没有人能够知道实际问题是什么。 - Sheridan
@Sheridan:这是一个很大的生活暗示:每当你发现自己说“我无法理解”或“我看不清楚”这样的事情时,请考虑这可能是你的理解或愿景的问题。你“无法理解”,因为我没有 做 那。我只是缩进了代码。仔细查看编辑历史记录。我已经做了。 - John Saunders
一世 没有 仔细看看 之前 我的评论,当我接受你的评论时,我想说它仍然存在 出现 好像你添加了那个代码......啊......那就是在 并排 视图。在其他观点中,我可以看到真实的情况。抱歉......在评论之前我应该​​仔细看看。 - Sheridan


答案:


您缺少服务配置

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

使用此配置,您不需要在代码中定义基址。


8
2018-01-11 17:27



谢谢回复。我没有在我的服务器控制台项目上正确设置app.config。我在host.Open()之前在代码中声明了绑定和行为;它工作。 - JoanComasFdz
如果这解决了您的问题,请不要忘记标记为答案 - InspiredBy


尝试更新现有服务引用时收到了同样的错误。事实证明,我在同一名称空间中拥有相同名称的数据协定。进一步的调查产生了真正的错误:

DataContract类型 [删除] 类型'无法添加到DataContractSet[删除]'在命名空间中使用相同的数据协定名称'DocumentInfo'[删除]'已经存在且合同不相同。

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

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

我在这里张贴这个,以防它可能帮助有同样问题的人。


3
2018-01-11 15:56



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


我得到了相同的错误消息,事实证明,问题是由于注释块中的文本

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

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


2
2018-06-28 15:28





我有同样的问题(当客户端没有“看到”“添加服务引用”菜单中的服务),而只使用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地址现在由客户端用于添加服务引用,客户端自动生成的配置使用net.tcp协议来调用该函数。


1
2017-09-13 11:16



这似乎是一个很好的解决方案,它似乎是逻辑,但一旦你的客户端生成,你需要http地址吗? - JoanComasFdz
如果您有一个客户端,则不需要http地址。但是如果将来可能需要生成一些客户端,最好将它放在配置中。 - Anna


也许对某人有帮助。

我的问题是在合同论证中,我在帮助下发现了它 事件查看器

操作[方法名称]具有参数或返回类型,该类型与MessageContractAttribute一起归属。为了使用消息合同表示请求消息,操作必须具有 单个参数 归因于MessageContractAttribute。为了使用消息协定表示响应消息,操作的返回值必须是使用MessageContractAttribute归属的类型,并且操作可能没有任何out或ref参数。

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


1
2017-08-08 14:28