2009-09-25 15 views
8

Mam zestaw umów serwisowych, które dzielą mój interfejs usług na fragmenty powiązanych funkcji. Obecnie wdrażam wszystkie kontrakty przy użyciu jednej klasy usług (można je podzielić później, ale na razie wystarczająca jest jedna klasa usług).Usługa WCF IIS obsługuje wiele umów serwisowych realizowanych przez pojedynczą usługę - jak udostępnić URI między punktami końcowymi za pomocą konfiguracji

Próbuję użyć konfiguracji punktów końcowych za pomocą pliku konfiguracyjnego (w przeciwieństwie do kodu za pośrednictwem kodu). Problem polega na tym, że otrzymuję ServiceActivationException, ponieważ dwa punkty końcowe (jeden dla każdej umowy serwisowej) próbują nasłuchiwać na tym samym komputerze. Szczegóły wyjątku mówią, że aby to osiągnąć, oba punkty końcowe muszą współdzielić obiekt wiązania, co ma sens, ale nie mogę wymyślić, jak to zrobić przez config (nie próbowałem tego robić przez kod, ponieważ jestem hostem w IIS, ale Mogę sobie wyobrazić, że jest to proste ćwiczenie do konfiguracji w kodzie).

Poniżej znajduje się config Obecnie używam (jest to nadal dev, więc nie jestem obecnie martwi się o kwestie bezpieczeństwa itp, że niektóre z tych ustawień może narazić):

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

Moje pytanie brzmi: jak udostępnić to powiązanie między dwoma punktami końcowymi?

Komentarze w this SO question sugerują, że mogę nie być w stanie tego zrobić, ale nie wierzę, że to prawda.

UPDATE 1 Według this MS publication co robię powinno być ok ...

Update2 Oto zawartość pliku SVC, czy to pomaga:

<%@ ServiceHost Language="VB" Debug="true" 
       Service="*********************.MidTierAccessService" 
       Factory="Microsoft.ServiceModel.Web.WebServiceHost2Factory" %> 

UPDATE 3 Oto szczegóły wyjątku:

Wiążące instan ce został już powiązany z odsłuchaniem URI "********************". Jeśli dwa punkty końcowe chcą współużytkować tę samą metodę ListenUri, muszą one również współużytkować tę samą instancję obiektu wiążącego, . Dwa będące w konflikcie punkty końcowe zostały określone w wywołaniach AddServiceEndpoint(), w pliku konfiguracyjnym lub w połączeniu z AddServiceEndpoint() i config.

UPDATE 4 Ok Tęskniłem this wcześniej, stwierdzając „Trzeba będzie używać adresów względnych podczas wystawiania więcej niż jeden punkt końcowy dla danej usługi .svc”. Przyczyna tego leży w związku z katalogiem wirtualnym IIS określającym adres bazowy usługi, czy ktoś może wyjaśnić to nieco bardziej szczegółowo, tj. Dlaczego usługi IIS potrzebują względnego adresowania dla każdej umowy.

Odpowiedz

7

Z mojego doświadczenia wynika, że ​​w ostatnim miesiącu wykonałem obszerną pracę z WCF, nie można udostępnić tego samego identyfikatora URI dla więcej niż jednego punktu końcowego. W WCF "usługa" nie jest definiowana przez implementację umowy, ale przez samą umowę (która również jest zgodna z WSDL i standardowymi praktykami SOA). Punkty końcowe pozwalają na wyeksponowanie jednej usługi za pośrednictwem wielu protokołów (i w związku z tym różnych adresów) , ale nie możesz udostępniać różnych usług pod tym samym adresem. Logicznie to nie zadziałałoby.

Przyjmijmy następujący scenariusz (co jest to, co staramy się osiągnąć):

IProductService exposed @ http://localhost/service 
ICategoryService exposed @ http://localhost/service 
IMetadataExchange exposed @ http://localhost/service/mex 

Jest to dość łatwe do uzyskania dostępu do końcowego MEX ... ma unikalny identyfikator URI. Jak jednak uzyskać dostęp do jednej z usług IProductService lub ICategoryService? Nic nie pozwala na odróżnienie dwóch innych niż URI. WCF nie ma nic, co pozwoliłoby mu na przesyłanie między wiadomościami, które mają trafić do IProductservice, a tymi, które powinny przejść do ICategoryService. Ponieważ oba używają tego samego identyfikatora URI, rzeczywiście masz konflikt. Każdy KONTRAKT usług musi być ujawniony poprzez unikalny URI. Każdy punkt końcowy, który wykorzystuje to samo dokładne wiązanie, musi używać odrębnego adresu.

Istnieje sposób na osiągnięcie tego, czego potrzebujesz. Problem polega na przekierowywaniu wiadomości. WCF nie obsługuje natywnie routingu komunikatów OOB, jednak zapewnia możliwość implementacji własnego routera wiadomości. (Lub, jeśli chcesz korzystać z beta-tech, .NET 4.0 jest dostarczany z routerem wiadomości po wyjęciu z pudełka, w oparciu o artykuły powiązane poniżej, ale z lepszą konfigurowalnością.) Michele Bustamante, prawdziwa czarodziejka WCF, dostarczyła pełna realizacja i artykuł opisujący wiadomość routingu pod następującymi linkami:

http://msdn.microsoft.com/en-us/magazine/cc500646.aspx http://msdn.microsoft.com/en-us/magazine/cc546553.aspx

ogólna idea jest taka, że ​​można skonfigurować jedną usługę, który nasłuchuje na jednym URI. Ta usługa używa wysyłania z użyciem symboli wieloznacznych do pojedynczej operacji usługi, która następnie określa, który unikalny identyfikator URI ma kierować każdą wiadomość. Możesz dokonać takiego wyboru w dowolny sposób, jednak najprostszy jest przez żądanie Działanie, zakładając, że każda akcja na twoich dwóch interfejsach, IProductService i ICategoryService, są globalnie unikalne. W rezultacie otrzymasz więcej usług, jednak ... sam router jest odrębną usługą WCF, która musi być hostowana tak jak każda inna.

+2

+1 za "prawdziwą czarodziejkę" – dan

+0

@dan: lol: D Dzięki. – jrista

Powiązane problemy