WCF IIS hosted service несколько сервисных контрактов, реализованных одной службой - как я могу поделиться uri между конечными точками через config
У меня есть набор сервисных контрактов, которые разделяют мой сервисный интерфейс на куски соответствующей функциональности. В настоящее время я реализую все контракты, используя один класс обслуживания (возможно, позже захочу разделить их, но пока достаточно одного класса обслуживания).
Я пытаюсь использовать configure конечные точки с помощью файла конфигурации (в отличие от via code). Проблема в том, что я получаю ServiceActivationException
, потому что две конечные точки (по одной для каждого контракта на обслуживание) пытаются слушать один и тот же uri. То детали исключения говорят, что для достижения этого две конечные точки должны совместно использовать объект привязки, что имеет смысл, но я не могу понять, как это сделать через config (я не пробовал делать это через код, поскольку я размещаю в IIS, но я могу себе представить, что это простое упражнение для настройки в коде).
Ниже приведена конфигурация, которую я использую в данный момент (это все еще dev, поэтому я в настоящее время не беспокоюсь о проблемах безопасности и т. д. что некоторые из этих настроек могут выставить):
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="CDC.WebPortal.MidTier.MidTierAccessService"
behaviorConfiguration="MidTierServiceBehaviour" >
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration="RestBindingConfiguration"
contract="****************************.IProductService" />
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration="RestBindingConfiguration"
contract="****************************.ICategoryService" />
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="RestBindingConfiguration"
maxReceivedMessageSize="104857600">
<readerQuotas maxStringContentLength="104857600"/>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MidTierServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Итак мой вопрос заключается в том, как разделить эту привязку между двумя конечными точками?
Комментарии вэтот так Вопрос предполагают, что я, возможно, не смогу этого сделать, но я не верю, что это правильно.
Обновление 1 согласно этой публикации MS то, что я делаю, должно быть в порядке...
UPDATE2 вот содержимое файла svc, если это поможет:
<%@ ServiceHost Language="VB" Debug="true"
Service="*********************.MidTierAccessService"
Factory="Microsoft.ServiceModel.Web.WebServiceHost2Factory" %>
UPDATE 3 Вот деталь исключения:
Экземпляр привязки уже имеет был связан, чтобы слушать Ури '********************'. Если две конечные точки хотят совместно использовать один и тот же ListenUri, они также должны совместно использовать одну и ту же привязку экземпляр объекта. Две конфликтующие конечные точки были либо указаны в Вызов функции AddServiceEndpoint() в файле конфигурации или комбинации функций AddServiceEndpoint() и конфиг.
UPDATE 4 Ok я пропустил это раньше, заявив: "вам нужно будет использовать относительные адреса при предоставлении более одной конечной точки для определенный.служба svc". Причина этого - что-то связанное с виртуальным каталогом IIS, определяющим базовый адрес службы, может ли кто-нибудь объяснить это немного более подробно, т. е. почему IIS нуждается в относительной адресации для каждого контракта.
1 ответ:
Насколько мне известно, и я провел обширную работу с WCF в прошлом месяце, вы не можете использовать один и тот же точный URI для более чем одной конечной точки. В WCF "услуга" определяется не выполнением контракта, а самим контрактом (который также следует WSDL и стандартной практике SOA.) Конечные точки позволяют предоставлять доступ к одной службе по нескольким протоколам (и, следовательно, по разным адресам), но вы не можете совместно использовать разные службы на одном и том же точном адресе. Логично, что это не сработает.
Предположим следующий сценарий (который вы пытаетесь выполнить):
IProductService exposed @ http://localhost/service ICategoryService exposed @ http://localhost/service IMetadataExchange exposed @ http://localhost/service/mex
Достаточно легко получить доступ к MEX endpoint...it имеет уникальный URI. Однако как получить доступ к IProductService или ICategoryService? Нет ничего, что позволяет вам различать эти два, кроме URI. WCF не имеет ничего, что позволило бы ему маршрутизировать сообщения, которые должны идти в IProductservice, и те, которые должны идти в ICategoryService. Поскольку оба используют один и тот же URI, у вас действительно есть конфликт. Каждый сервисный контракт должен быть представлен через уникальный URI. Каждая конечная точка, использующая одну и ту же точную привязку, должна использовать отдельный адрес.
Есть способ достичь того, что вам нужно. Проблема заключается в маршрутизации сообщений. WCF изначально не поддерживает маршрутизацию сообщений OOB, однако предоставляет возможность реализовать собственный маршрутизатор сообщений. (Или, если вы хотите использовать beta tech, .NET 4.0 поставляется с маршрутизатором сообщений из коробка, основанная на статьях, связанных ниже, но с улучшенной конфигурацией.) Мишель Бустаманте, настоящая волшебница WCF, предоставила полную реализацию и статью, описывающую маршрутизацию сообщений по следующим ссылкам:Http://msdn.microsoft.com/en-us/magazine/cc500646.aspx http://msdn.microsoft.com/en-us/magazine/cc546553.aspx
Общая идея заключается в том, что вы настраиваете одну службу, которая слушает один URI. Эта служба использует подстановочные знаки отправка в одну операцию службы, которая затем определяет, к какому уникальному URI направить каждое сообщение. Вы можете сделать определение любым способом, однако самый простой - через действие запроса, предполагая, что каждое действие на ваших двух интерфейсах, IProductService и ICategoryService, глобально уникально. Однако в конечном итоге вы получите больше услуг...сам маршрутизатор-это отдельная служба WCF, которая должна быть размещена так же, как и любая другая.