WCF и несколько заголовков хостов

Мой сайт работодателей имеет несколько имен хостов, которые все попадают на тот же сервер, и мы просто показываем разные скины для целей брендинга.

К сожалению, WCF, похоже, не работает в этой ситуации.

Я пробовал переопределить хост по умолчанию с помощью настраиваемого хоста factory.

Это не приемлемое решение, потому что оно должно работать от всех хостов, а не только от 1.

Я также посмотрел этот пост в блоге, но либо я не мог заставить его работать, либо он не предназначен для решения моей проблемы проблема.

Ошибка, которую я получаю, это "Эта коллекция уже содержит адрес со схемой http"

Должен быть способ настроить это, пожалуйста, помогите:)

Ответ 1

Если вы не помещаете адрес в конечную точку, он должен решить, какой сервер попадает в службу. Я использую этот код, и он разрешает как мой .local адрес, так и мой адрес .com из IIS.

<system.serviceModel>
    <services>
        <service name="ServiceName" behaviorConfiguration="ServiceName.Service1Behavior">
            <endpoint address="" binding="wsHttpBinding" contract="iServiceName">
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="ServiceName.Service1Behavior">
                <!-- 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="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

Ответ 2

Я не думаю, что решение базового адреса размещено выше, будет работать на веб-сайтах, размещенных на IIS (OP упомянул, что это было для его веб-сайта работодателя).

Смотрите это сообщение в блоге

Кроме того, другой ответ далее thaBadDawg не будет работать там, где указаны несколько заголовков хоста, вы просто получите ошибки, о которых упоминает OP ( "Эта коллекция уже содержит адрес с схема http".)

Я не думаю, что какое-либо из решений, упомянутых до сих пор, будет работать, потому что не похоже, что WCF позволяет одной службе быть доступной для одного сайта с несколькими заголовками хостов со всех сайтов. Единственным обходным решением, которое я смог найти для .Net 3.5 (и ниже), является создание другого контракта для каждого из заголовков хоста и использование настраиваемого ServiceHostFactory для использования правильного заголовка хоста на основе того, какой контракт указан. Это совсем не практично. По-видимому, .NET 4.0 решит эту проблему.

Ответ 3

Я встретил эту проблему несколько дней назад. На самом деле у меня такая же ситуация, что Рю описал первоначально в его вопросе. У нас есть один виртуальный каталог для многих клиентов, но у каждого из них есть своя привязка. Как " http://company1.product.com", " http://company2.product.com" и т.д.

Решение, описанное здесь работает. Но какая цена! Мы должны менять web.config каждый раз, когда нам нужно добавить новое связывание. А также web.config должен содержать абсолютный префикс пути например <add prefix="http://company1.product.com"/>.

Можно обойти первую проблему. Я написал свой собственный CustomHostFactory для службы WCF, где я динамически добавляю конечные точки. И это конечные точки, которые я извлекаю из привязок IIS (есть способ получить информацию от IIS).

Вот пример кода:

protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
    var serviceHost = base.CreateServiceHost(serviceType, baseAddresses);
    var webHttpBinding = new WebHttpBinding();
    var serviceEndpoint1 = serviceHost.AddServiceEndpoint(typeof(IService), webHttpBinding,
                                                         "http://company2.product.com/WCFService/Service.svc");

    var serviceEndpoint2 = serviceHost.AddServiceEndpoint(typeof(IService), webHttpBinding,
                                                 "http://company1.product.com/WCFService/Service.svc");

    var webHttpBehavior = new WebHttpBehavior();

    serviceEndpoint1.Behaviors.Add(webHttpBehavior);
    serviceEndpoint2.Behaviors.Add(webHttpBehavior);

    return serviceHost;
}

И вместо URL-адресов конечных точек hardcoding вы можете получить их из IIS. Но ServiceHost создается один раз, когда приложение запускается. Поэтому, если вам нужно добавить новое связывание, вам следует перезапустить IIS. Это не решение для нас.

Вот почему мы решили перейти в asmx (как описано здесь). И подождите, пока релиз Framework 4.0, где должны поддерживаться несколько привязок.

Ответ 4

Простым обходным решением, которое не связано с изменением кода или конфигурации, является создание еще одного веб-сайта в IIS, который указывает на тот же физический каталог и тот же пул приложений, но с другой привязкой заголовка хоста. Это можно сделать так же, как и у разных имен хостов.

Ответ 5

Я уверен, что вы уже поняли это, но просто для удовольствия я все равно отправлю.

У меня была эта точная проблема, и я потратил на нее все время, пытаясь понять это. Лучшим решением является размещение базовых адресов хоста в определении службы, что позволяет службе работать под этими несколькими адресами. Чтобы это решение работало, вам по-прежнему необходимо, чтобы ServiceHostFactory был переопределен. Поскольку вы уже это сделали, просто оставьте его там.

<service behaviorConfiguration="ServiceBehaviour" name="Api.Service">
    <endpoint address="soap" binding="basicHttpBinding" contract="Api.IService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://host1.com/Api" />
        <add baseAddress="http://host2.com/Api" />
      </baseAddresses>
    </host>
  </service>