Метаданные WCF содержат ссылку, которая не может быть разрешена

Я потратил пару часов на поиск этой ошибки, и я протестировал почти все, что есть в Google.

Я хочу получить доступ к службе с использованием 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();
    }
}

Теперь я хочу создать клиента, но я его не понимаю. Я использовал ссылку "Добавить службу" и svcutil напрямую, но я получаю эту ошибку:


C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC > svcutil.exe net.tcp://loc alhost: 5050/Service1 Microsoft (R) Service Model Инструмент метаданных [Microsoft (R) Windows (R) Communication Foundation, Версия 4.0.30319.1] Авторское право (c) Корпорация Microsoft. Все права зарезервирован.

Попытка загрузить метаданные из 'net.tcp://localhost: 5050/Service1' с использованием W-метаданных Exchange. Эта URL-адрес не поддерживает DISCO. Средство метаданных модели службы Microsoft (R) [Microsoft (R) Windows (R) Communication Foundation, версия 4.0.30319.1] Авторское право (c) Корпорация Microsoft. Все права защищены.

Ошибка: невозможно получить метаданные из net.tcp://localhost: 5050/Service1

Если это служба Windows (R) Communication Foundation, к которой вы убедитесь, что вы включили публикацию метаданных в указанном дополнении. Чтобы помочь в публикации метаданных, обратитесь к документу 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 interrupción de una conexión existente por el host remoto

Если вам нужна дополнительная помощь, введите "svcutil/?"


Итак, я могу разместить службу без проблем, но я не могу создать прокси.

Я пробовал почти любую конфигурацию, которую я нашел, но я думаю, что текущий web.config правильный. Существуют поведения, безопасность и привязки с использованием mex, используемые конечными точками.

Я попытался создать app.config и установить его в ту же папку с svcutil.exe.

Ответ 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>

С помощью этой конфигурации вам не нужно определять базовый адрес в коде.

Ответ 2

Я получил ту же ошибку при попытке обновить существующую ссылку на службу. Оказывается, у меня были контракты с одним и тем же именем в одном и том же пространстве имен. Дальнейшие исследования дали реальную ошибку:

DataContract для типа [redacted] не может быть добавлен в DataContractSet, поскольку тип '[redacted]' с тем же именем контракта данных 'DocumentInfo' в пространстве имен '[redacted]' уже присутствует, а контракты не являются эквивалентными.

Я изменил DataContract, чтобы указать имя для одного из классов.

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

Я размещаю это здесь, если это может помочь кому-то с той же проблемой.

Ответ 3

Я получал такое же сообщение об ошибке, и, как выяснилось, проблема связана с текстом в блоке комментариев

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

После удаления таких символов из блока комментариев все работает отлично

Ответ 4

У меня была та же проблема (когда клиент не "видел" службу в меню "Добавить ссылку на службу" ), используя только привязку tcp. После попытки добавить Behavior у меня была моя служба, чтобы закончить с исключением, потому что он не нашел правильный адрес. Я не знаю, если это лучшая идея, но вы можете добавить второй базовый адрес в качестве 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 для вызова функции.

Ответ 5

Возможно, это будет полезно для кого-то.

Моя проблема была в аргументе контракта, и я обнаружил ее с помощью средства просмотра событий:

Операция [Имя метода] либо имеет параметр, либо тип возврата, который приписывается MessageContractAttribute. Чтобы представить сообщение запроса с использованием Контракта сообщения, операция должна иметь одиночный параметр, связанный с MessageContractAttribute. Чтобы представить ответное сообщение с использованием Контракта с сообщением, возвращаемое значение операции должно быть типом, который присваивается MessageContractAttribute, и операция может не иметь каких-либо параметров или ref.

Итак, если вы добавили несколько аргументов, уже имеющих аргумент [MessageContract], вы увидите ошибку. Совершенно не очевидно.