WCF устанавливает конечную точку и привязку динамически в коде

Да, я читал другие вопросы на SO, MSDN и других сайтах, но я не нашел ответов настолько ясных, насколько я могу понять. Мне нужно установить ссылки WCF моего приложения Silverlight относительно сайта, с которого оно загружено, но я не могу заставить его работать. С самим сервисом проблем нет, он работает. Когда я перехожу с локального на свой реальный сервер, в моем приложении SL появляются ошибки с жалобами на отсутствие соединения с localhost.

Вот мой ServiceReferences.ClientConfig файл:

    <configuration>
        <system.serviceModel>
            <bindings>
                <customBinding>
                    <binding name="CustomBinding_AccountManager">
                        <binaryMessageEncoding />
                        <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                    </binding>
                    <binding name="CustomBinding_FileManager">
                        <binaryMessageEncoding />
                        <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                    </binding>
                    <binding name="CustomBinding_SiteManager">
                        <binaryMessageEncoding />
                        <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                    </binding>
                </customBinding>
            </bindings>
            <client>
                <endpoint address="http://localhost:60322/AccountManager.svc"
                    binding="customBinding" bindingConfiguration="CustomBinding_AccountManager"
                    contract="AccountManager.AccountManager" name="CustomBinding_AccountManager" />
                <endpoint address="http://localhost:60322/FileManager.svc" binding="customBinding"
                    bindingConfiguration="CustomBinding_FileManager" contract="FileManager.FileManager"
                    name="CustomBinding_FileManager" />
                <endpoint address="http://localhost:60322/SiteManager.svc" binding="customBinding"
                    bindingConfiguration="CustomBinding_SiteManager" contract="SiteManager.SiteManager"
                    name="CustomBinding_SiteManager" />
            </client>
        </system.serviceModel>
    </configuration>

Да, я оптимизирую размеры буфера / сообщения и знаю возможные эксплойты DoS, пока забудем об этом, они мне нужны для передачи больших файлов. Подход, который я попробовал, заключается в том, что при создании экземпляров клиентов я использовал этот код:

    fileManager = new FileManagerClient(new BasicHttpBinding(), new EndpointAddress("http://" + Settings.Host + "/FileManager.svc"));
    accManager = new AccountManagerClient(new BasicHttpBinding(), new EndpointAddress("http://" + Settings.Host + "/AccountManager.svc"));

где Settings.Host мой собственный метод, который возвращает мне хост, с которого работает приложение SL, проверено, работает. Когда я загрузил свой XAP и попытался, он все еще хотел пойти на http://localhost:60322/AccountManager.svc После дальнейшего изучения я понял, что в невидимых файлах все еще много ссылок на localhost:

AccountManager.disco:

<?xml version="1.0" encoding="utf-8"?>
<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
  <contractRef ref="http://localhost:60322/AccountManager.svc?wsdl" docRef="http://localhost:60322/AccountManager.svc" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
</discovery>

Части AccountManager.wsdl: ... <wsdl:import namespace="" location="http://localhost:60322/AccountManager.svc?wsdl=wsdl0" />...... [много объявлений операций]...

<wsdl:service name="AccountManager">
    <wsdl:port name="CustomBinding_AccountManager" binding="tns:CustomBinding_AccountManager">
      <soap12:address location="http://localhost:60322/AccountManager.svc" />
      <wsa10:EndpointReference>
        <wsa10:Address>http://localhost:60322/AccountManager.svc</wsa10:Address>
      </wsa10:EndpointReference>
    </wsdl:port>
  </wsdl:service>

Часть AccountManager1.xsd:

<xs:import schemaLocation="http://localhost:60322/AccountManager.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/Leftouch.Data.Summary" />

Часть configuration.svcinfo:

<endpoint normalizedDigest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://localhost:60322/AccountManager.svc&quot; binding=&quot;customBinding&quot; bindingConfiguration=&quot;CustomBinding_AccountManager&quot; contract=&quot;AccountManager.AccountManager&quot; name=&quot;CustomBinding_AccountManager&quot; /&gt;" digest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://localhost:60322/AccountManager.svc&quot; binding=&quot;customBinding&quot; bindingConfiguration=&quot;CustomBinding_AccountManager&quot; contract=&quot;AccountManager.AccountManager&quot; name=&quot;CustomBinding_AccountManager&quot; /&gt;" contractName="AccountManager.AccountManager" name="CustomBinding_AccountManager" />

Часть Reference.svcmap:

</ClientOptions>
  <MetadataSources>
    <MetadataSource Address="http://localhost:60322/AccountManager.svc" Protocol="http" SourceId="1" />
  </MetadataSources>
  <Metadata>
    <MetadataFile FileName="AccountManager2.xsd" MetadataType="Schema" ID="e473b2d5-7af3-4390-87c3-a4fc3f54fb96" SourceId="1" SourceUrl="http://localhost:60322/AccountManager.svc?xsd=xsd2" />
    <MetadataFile FileName="AccountManager1.xsd" MetadataType="Schema" ID="fd3a1ae0-b38b-4586-8622-5b0ee07e39fb" SourceId="1" SourceUrl="http://localhost:60322/AccountManager.svc?xsd=xsd0" />
    <MetadataFile FileName="AccountManager.xsd" MetadataType="Schema" ID="6a49ee64-6eac-40e2-bcff-26418435e777" SourceId="1" SourceUrl="http://localhost:60322/AccountManager.svc?xsd=xsd1" />
    <MetadataFile FileName="AccountManager.disco" MetadataType="Disco" ID="9ec9a8cc-0cf0-4264-a526-b5a6c08f7d36" SourceId="1" SourceUrl="http://localhost:60322/AccountManager.svc?disco" />
    <MetadataFile FileName="AccountManager1.wsdl" MetadataType="Wsdl" ID="54a5b2c0-9d0e-4043-a7e4-d27ae6674bfc" SourceId="1" SourceUrl="http://localhost:60322/AccountManager.svc?wsdl=wsdl0" />
    <MetadataFile FileName="AccountManager.wsdl" MetadataType="Wsdl" ID="f8923013-3a6c-412b-b7da-bee5a5a7bb64" SourceId="1" SourceUrl="http://localhost:60322/AccountManager.svc?wsdl" />

... и ВСЕ эти снова для других 2 услуг тоже.

Я не являюсь мастером веб-сервисов / привязок / конечных точек / контрактов на операции или каких-либо связанных вещей. Я просто хочу, чтобы моя полностью уже работающая (когда URI жестко задан) система работала для относительных URI, это все, что мне нужно. Там должно быть простое решение. Может кто-нибудь объяснить, на что именно похожи эти типы файлов и декларации, которые важны, а какие необязательны, и как я могу создавать динамические ссылки на сервисы в чистом виде. Пожалуйста, с объяснениями. Я уже видел много постов и статей о динамических привязках и ссылках на сервисы, но, честно говоря, все запуталось, и я ничего не понял из этого. Любая конструктивная критика и решения приветствуются.

1 ответ

Решение

Использует ли файл конфигурации для вашей службы (не клиента) конечные точки с полностью определенными адресами (например, в конфигурации клиента)? Если это так, то причина, по которой вы видите все эти ссылки на локальный хост, заключается в том, что когда вы добавляете ссылку на службу, она будет переносить этот адрес в сгенерированных файлах.

Обновите конечную точку в файле конфигурации службы, чтобы использовать либо полный адрес на этом компьютере (т. Е. http://somname.com/service.svc) или установите baseAddresses в файле конфигурации на имя компьютера.

Кроме того, если вы используете WCF 4.0 (VS 2010/.NET 4.0), вы можете сделать так, чтобы WCF создал конечную точку по умолчанию для ваших служб, полностью исключив конечные точки из файла конфигурации (насколько я понимаю - мы сейчас перехожу на 4.0 на работе, так что я не играл с новыми функциями).

ИЗМЕНЕНО ДЛЯ ДОБАВЛЕНИЯ

Новый подход, та же основная идея (что URI импортируется откуда-то). Исходя из ваших комментариев ниже, похоже, что конфигурация вашего сервиса настроена нормально, без жестко закодированных URI, указывающих на localhost.

Когда вы перемещаете свое приложение на целевой (ые) сервер (ы), вы также обновляете свою ссылку на свою службу (с помощью Добавить ссылку на службу) или просто перемещаете файлы, которые генерируются из вашего локального ящика, на целевой сервер?

Если да, мне интересно, может ли это быть источником вашей проблемы. Я думаю, что указание адреса службы при создании клиента должно переопределить что-либо в файлах, связанных с WSDL, но, возможно, это не так.

Что-то попробовать:

Удалить <client> раздел из вашего Web.config. Затем, когда вы создаете клиент, сделайте так:

fileManager = new FileManagerClient(new BasicHttpBinding("CustomBinding_FileManager"), new EndpointAddress("http://" + Settings.Host + "/FileManager.svc"));

Убедитесь, что вы передали имя раздела конфигурации привязки в BasicHttpBinding конструктор, в противном случае вы получите привязку со значениями по умолчанию, а не с большими значениями, которые вы указали.

Идея здесь состоит в том, чтобы исключить любую вероятность того, что настройки файла конфигурации клиента переопределяют то, что вы передаете при создании FileManagerClient.

Я бы посоветовал обновлять ссылку на службу для каждого развертывания на каждом отдельном сервере менее чем идеально - то, что вы пытаетесь выполнить, имеет смысл. Я делаю нечто подобное в написанном n-уровневом приложении - единственная разница в том, что я не использую ссылки на сервисы, я генерирую прокси через SvcUtil, а затем генерирую каналы через ChannelFactory<T>, который является еще одним маршрутом, на который вы можете посмотреть.

Если ничего из этого не помогло, пожалуйста, напишите мне по электронной почте (мой адрес электронной почты указан в моем профиле) - это может быть легче выяснить с помощью обмена электронной почтой, а затем опубликовать окончательное решение.

Другие вопросы по тегам