WCF und Multiple Host Header oder „This collection already contains an address with scheme http. There can be at most one address per scheme in this collection. „

Liebe Silverlight – Gemeinde

Nach einer kleinen Ewigkeit melde ich mich bei euch mit einem Problem zurück, in der Hoffnung, Hilfe oder Lösungen zu bekommen.
Das Problem hat sich im Zusammenhang von Silverlight-Applikationen auf Webseiten mit "mutliplen Host Headern" gezeigt. Wird zum kommunzieren von Client- und Server-Seite ein WCF Service benutzt, bekommt man unweigerlich die Fehlermeldung:

errorthis

Wie schon erwähnt, tritt das Problem nur bei "multiplen Host Headern" auf.  Vereinfacht gesagt, werden "multiple Host Header" benötigt, wenn man über verschiedene URL's auf die gleiche Webseite gelangen will. Auf dem unteren Bild sieht man zwei solche Host Header.

mHostehader

Mit mehreren Host Headern wird unser hübscher WCF Service ein bisschen verwirrt und weiss nicht mehr wo er sich denn jetzt befindet. Und weil er das nicht weiss, findet er sich sozusagen selber nicht.
Nach kurzem googlen, hat sich herausgestellt dass man im "Web.config" – File nur ganz einfach folgendes eingeben muss, damit's funktioniert:

<serviceHostingEnvironment>
       <baseAddressPrefixFilters>
           <add prefix="http://*****.in4out.ch"/>
      </baseAddressPrefixFilters>
 </serviceHostingEnvironment> 

Jetzt funktioniert der WCF Service allerdings nur noch auf der URL http://*****.in4out.ch, dafür aber nicht mehr auf http://*****.in4out-ag.local.
Es gibt auch keine Möglichkeit zwei solcher "baseAddressPrefixFilters" zu setzen, denn dann weiss der Webservice wieder nicht wo er sich befindet.

Nach weiterem googlen stiess ich dabei auf folgendes: CreateServiceHost
Dabei lautet die Definition von Microsoft:
"Erstellt eine Instanz der Dienstklasse, die über die angegebenen Basisadressen verfügt."

Nach dem Durchstöbern zahlreicher Foren, bin ich auf das Untenstehende gekommen.

1. Man mache eine neue Klasse im App-Code-Ordner und nenne diese "CustomHostFactory"
2. Man kopiere folgenden Code rein:

    Imports Microsoft.VisualBasic
     Imports System.ServiceModel.Activation
     Imports System.ServiceModel
     Imports System.IO
     
     Public Class CustomHostFactory
             Inherits ServiceHostFactory
                 Protected Overloads Overrides Function CreateServiceHost(ByVal serviceType As Type, ByVal baseAddresses As Uri()) As ServiceHost
                      Dim host As ServiceHost
                      host = New ServiceHost(serviceType, baseAddresses(0))
                      Return host
                 End Function
     End Class 

3. Man setze im "svc"- File das "Factory"- Property:

<%@ ServiceHost Language="VB" Debug="false" Service="i4BambiService" CodeBehind="~/App_Code/i4Bambi/i4BambiService.vb" Factory="CustomHostFactory"%> 

Nun weiter zur Erklärung…

Meistens wird die Funktion "CreateServiceHost" automatisch mit dem Aufrufen des WCF als Teil der Dienstaktivierung aufgerufen, sodass die Methode nicht manuell gesetzt werden muss.
Um aber steuern zu können, welchen Host Header der Webservice nun nehmen soll, benötige ich die Methode hier. Man werfe doch nun bitte einen Blick auf den Parameter "baseAddresses" in dieser Methode.

In diesen Parameter werden alle verschiedene Host Header geschrieben. In meinem Fall also: http://*****.in4out.ch und   http://*****.in4out-ag.local.
Mit dem Integer in der Klammer (hier also "0") wird angeben welcher Host Header aus dem Array denn gewählt werden soll.
Wenn man nun noch mals folgendes betrachtet:

mHostehader

ist es in diesem Fall nun der erste Host Header, nämlich: http://*****.in4out-ag.local

Ich kann nun zwar im Code-Behind steuern, welchen Host Header ich denn gerne haben möchte, allerdings kann ich hier keine Abfragen machen und so den Integer auch nicht dynamisch werden lassen. Wie es scheint, wird nur jedesmal nach dem Compilieren der Host Header neu gesetzt. Ich kann auch den Pfad zum Webservice nicht dynamisch machen.

So und jetzt kommt ihr zum Zug. Habt ihr vielleicht eine Idee für mich, oder hab ich einfach was grundlegendes falsch verstanden? Ich bitte um eure Mithilfe.
Noch ne kurze Zusammenfassung: Ich suche nach einem Weg, wie mein Webservice bei beliebig vielen Host Headern funktionieren kann, ohne dass ich manuell etwas ändern oder absolute Pfade vergeben muss.
Ich danke euch schon mal im Vorraus.

2 Kommentare zu “WCF und Multiple Host Header oder „This collection already contains an address with scheme http. There can be at most one address per scheme in this collection. „

  1. Markus 22.02.2010 - 16:27

    Das Problem mit den alternativen Website-Namen kann einfach gelöst werden durch die explizite Angabe derselben in der Form:

    <endpoint address="http://fqdn1/service.svc&quot; binding="…
    <endpoint address="http://fqdn1/service.svc&quot; binding="…

    Zusätzliche Informationen s. auch http://blogs.msdn.com/rampo/archive/2008/02/11/how-can-wcf-support-multiple-iis-binding-specified-per-site.aspx

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


The reCAPTCHA verification period has expired. Please reload the page.