Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die gesamte Kommunikation mit einem Windows Communication Foundation (WCF)-Dienst erfolgt über seine Endpunkte. Jede ServiceEndpoint enthält ein Address, ein Binding und ein Contract. Der Vertrag gibt an, welche Vorgänge verfügbar sind. Die Bindung gibt an, wie mit dem Dienst kommuniziert werden soll, und die Adresse gibt an, wo der Dienst gefunden werden soll. Jeder Endpunkt muss über eine eindeutige Adresse verfügen. Die Endpunktadresse wird durch die EndpointAddress Klasse dargestellt, die einen URI (Uniform Resource Identifier) enthält, der die Adresse des Diensts, eine Identity, die die Sicherheitsidentität des Diensts darstellt, und eine Sammlung optionaler Headers. Die optionalen Header bieten detailliertere Adressierungsinformationen zum Identifizieren oder Interagieren mit dem Endpunkt. Beispielsweise können Kopfzeilen angeben, wie eine eingehende Nachricht verarbeitet wird, wo der Endpunkt eine Antwortnachricht senden soll oder welche Instanz eines Diensts zum Verarbeiten einer eingehenden Nachricht von einem bestimmten Benutzer verwendet werden soll, wenn mehrere Instanzen verfügbar sind.
Definition einer Endpunktadresse
In WCF modelliert ein EndpointAddress eine Endpunktreferenz (EPR), wie im WS-Addressing Standard definiert.
Der Adress-URI für die meisten Transporte weist vier Teile auf. Dieser URI http://www.fabrikam.com:322/mathservice.svc/secureEndpoint
weist beispielsweise die folgenden vier Teile auf:
Schema: http:
Computer:
www.fabrikam.com
(Optional) Port: 322
Pfad: /mathservice.svc/secureEndpoint
Ein Teil des EPR-Modells besteht darin, dass jeder Endpunktverweis einige Referenzparameter enthalten kann, die zusätzliche Identifikationsinformationen hinzufügen. In WCF werden diese Referenzparameter als Instanzen der AddressHeader Klasse modelliert.
Die Endpunktadresse für einen Dienst kann entweder mithilfe von Code oder deklarativ über die Konfiguration angegeben werden. Das Definieren von Endpunkten im Code ist in der Regel nicht praktikabel, da sich die Bindungen und Adressen für einen bereitgestellten Dienst in der Regel von denen unterscheiden, die während der Entwicklung des Diensts verwendet werden. Im Allgemeinen ist es praktischer, Dienstendpunkte mithilfe von Konfiguration und nicht mit Code zu definieren. Durch das Trennen von Bindungs- und Adressierungsinformationen vom Code können diese geändert werden, ohne dass die Anwendung neu kompiliert und bereitgestellt werden muss. Wenn keine Endpunkte im Code oder in der Konfiguration angegeben sind, fügt die Laufzeit einen Standardendpunkt für jede Basisadresse für jeden vom Dienst implementierten Vertrag hinzu.
Es gibt zwei Möglichkeiten, Endpunktadressen für einen Dienst in WCF anzugeben. Sie können eine absolute Adresse für jeden Endpunkt angeben, der dem Dienst zugeordnet ist, oder Sie können eine Basisadresse für den ServiceHost Dienst angeben und dann eine Adresse für jeden Endpunkt angeben, der diesem Dienst zugeordnet ist, der relativ zu dieser Basisadresse definiert ist. Sie können jede dieser Prozeduren verwenden, um die Endpunktadressen für einen Dienst in der Konfiguration oder im Code anzugeben. Wenn Sie keine relative Adresse angeben, verwendet der Dienst die Basisadresse. Sie können auch mehrere Basisadressen für einen Dienst haben, aber jedem Dienst ist nur eine Basisadresse pro Transportart erlaubt. Wenn Sie über mehrere Endpunkte verfügen, von denen jede mit einer anderen Bindung konfiguriert ist, müssen ihre Adressen eindeutig sein. Endpunkte, die dieselbe Bindung verwenden, aber unterschiedliche Verträge haben, können dieselbe Adresse verwenden.
Beim Hosten mit IIS verwalten Sie die ServiceHost Instanz nicht selbst. Die Basisadresse ist immer die Adresse, die in der SVC-Datei für den Dienst angegeben ist, wenn sie in IIS gehostet wird. Sie müssen also relative Endpunktadressen für von IIS gehostete Dienstendpunkte verwenden. Das Bereitstellen einer vollqualifizierten Endpunktadresse kann zu Fehlern bei der Bereitstellung des Diensts führen. Weitere Informationen finden Sie unter Bereitstellen eines von IIS gehosteten WCF-Diensts.
Definieren von Endpunktadressen in der Konfiguration
Verwenden Sie das <Endpunktelement> , um einen Endpunkt in einer Konfigurationsdatei zu definieren.
<configuration>
<system.serviceModel>
<services>
<service name="UE.Samples.HelloService"
behaviorConfiguration="HelloServiceBehavior">
<endpoint address="/Address1"
binding="basicHttpBinding"
contract="UE.Samples.IHello"/>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HelloServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Wenn die Open Methode aufgerufen wird (d. h. wenn die Hostanwendung versucht, den Dienst zu starten), sucht das System nach einem <Dienstelement> mit einem Namensattribut, das "UE.Samples.HelloService" angibt. Wenn das <Dienstelement> gefunden wird, lädt das System die angegebene Klasse und erstellt Endpunkte mithilfe der in der Konfigurationsdatei bereitgestellten Endpunktdefinitionen. Dieser Mechanismus ermöglicht es Ihnen, einen Dienst mit zwei Codezeilen zu laden und zu starten, während die Bindungs- und Adressierungsinformationen aus Ihrem Code herausgehalten werden. Der Vorteil dieses Ansatzes besteht darin, dass diese Änderungen vorgenommen werden können, ohne die Anwendung erneut kompilieren oder erneut bereitstellen zu müssen.
Die optionalen Kopfzeilen werden in einer <Kopfzeile> deklariert. Nachfolgend sehen Sie ein Beispiel für die Elemente, die zum Angeben von Endpunkten für einen Dienst in einer Konfigurationsdatei verwendet werden, die zwischen zwei Headern unterscheidet: "Gold"-Clients von http://tempuri1.org/
und "Standard"-Clients von http://tempuri2.org/
. Der Client, der diesen Dienst aufruft<, muss über die entsprechenden> Header in der Konfigurationsdatei verfügen.
<configuration>
<system.serviceModel>
<services>
<service name="UE.Samples.HelloService"
behaviorConfiguration="HelloServiceBehavior">
<endpoint address="/Address1"
binding="basicHttpBinding"
contract="UE.Samples.IHello">
<headers>
<Member xmlns="http://tempuri1.org/">Gold</Member>
</headers>
</endpoint>
<endpoint address="/Address2"
binding="basicHttpBinding"
contract="UE.Samples.IHello">
<headers>
<Member xmlns="http://tempuri2.org/">Silver</Member>
</headers>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HelloServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Kopfzeilen können auch für einzelne Nachrichten anstelle aller Nachrichten auf einem Endpunkt festgelegt werden (wie zuvor dargestellt). Dies geschieht, indem mit OperationContextScope ein neuer Kontext in einer Clientanwendung erstellt wird, um der ausgehenden Nachricht einen benutzerdefinierten Header hinzuzufügen, wie im folgenden Beispiel gezeigt.
SampleServiceClient wcfClient = new SampleServiceClient(new InstanceContext(this));
try
{
using (OperationContextScope scope = new OperationContextScope(wcfClient.InnerChannel))
{
MessageHeader header
= MessageHeader.CreateHeader(
"Service-Bound-CustomHeader",
"http://Microsoft.WCF.Documentation",
"Custom Happy Value."
);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
// Making calls.
Console.WriteLine("Enter the greeting to send: ");
string greeting = Console.ReadLine();
//Console.ReadLine();
header = MessageHeader.CreateHeader(
"Service-Bound-OneWayHeader",
"http://Microsoft.WCF.Documentation",
"Different Happy Value."
);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
// One-way
wcfClient.Push(greeting);
this.wait.WaitOne();
// Done with service.
wcfClient.Close();
Console.WriteLine("Done!");
Console.ReadLine();
}
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
Dim wcfClient As New SampleServiceClient(New InstanceContext(Me))
Try
Using scope As New OperationContextScope(wcfClient.InnerChannel)
Dim header As MessageHeader = MessageHeader.CreateHeader("Service-Bound-CustomHeader", _
"http://Microsoft.WCF.Documentation", "Custom Happy Value.")
OperationContext.Current.OutgoingMessageHeaders.Add(header)
' Making calls.
Console.WriteLine("Enter the greeting to send: ")
Dim greeting As String = Console.ReadLine()
'Console.ReadLine();
header = MessageHeader.CreateHeader("Service-Bound-OneWayHeader", _
"http://Microsoft.WCF.Documentation", "Different Happy Value.")
OperationContext.Current.OutgoingMessageHeaders.Add(header)
' One-way
wcfClient.Push(greeting)
Me.wait.WaitOne()
' Done with service.
wcfClient.Close()
Console.WriteLine("Done!")
Console.ReadLine()
End Using
Catch timeProblem As TimeoutException
Console.WriteLine("The service operation timed out. " & timeProblem.Message)
Console.ReadLine()
wcfClient.Abort()
Catch commProblem As CommunicationException
Console.WriteLine("There was a communication problem. " & commProblem.Message)
Console.ReadLine()
wcfClient.Abort()
End Try
Endpunktadresse in Metadaten
Eine Endpunktadresse wird in der Web Services Description Language (WSDL) als WS-Addressing EndpointReference
(EPR)-Element innerhalb des entsprechenden Endpunktelements wsdl:port
dargestellt. Der EPR enthält die Adresse des Endpunkts sowie alle Adresseigenschaften. Beachten Sie, dass der EPR in wsdl:port
soap:Address
ersetzt, wie im folgenden Beispiel gezeigt.
Definieren von Endpunktadressen im Code
Eine Endpunktadresse kann im Code mit der EndpointAddress Klasse erstellt werden. Der für die Endpunktadresse angegebene URI kann ein vollqualifizierter Pfad oder ein Pfad sein, der relativ zur Basisadresse des Diensts ist. Der folgende Code veranschaulicht, wie eine Instanz der EndpointAddress Klasse erstellt und der ServiceHost Instanz hinzugefügt wird, die den Dienst hostet.
Im folgenden Beispiel wird veranschaulicht, wie die vollständige Endpunktadresse im Code angegeben wird.
Uri baseAddress = new Uri("http://localhost:8000/HelloService");
string address = "http://localhost:8000/HelloService/MyService";
using (ServiceHost serviceHost = new ServiceHost(typeof(HelloService), baseAddress))
{
serviceHost.AddServiceEndpoint(typeof(IHello), new BasicHttpBinding(), address);
serviceHost.Open();
Console.WriteLine("Press <enter> to terminate service");
Console.ReadLine();
serviceHost.Close();
}
Im folgenden Beispiel wird veranschaulicht, wie der Basisadresse des Diensthosts eine relative Adresse ("MyService") hinzugefügt wird.
Uri baseAddress = new Uri("http://localhost:8000/HelloService");
using (ServiceHost serviceHost = new ServiceHost(typeof(HelloService), baseAddress))
{
serviceHost.AddServiceEndpoint(typeof(IHello), new BasicHttpBinding(), "MyService");
serviceHost.Open();
Console.WriteLine("Press <enter> to terminate service");
Console.ReadLine();
serviceHost.Close();
}
Hinweis
Eigenschaften des ServiceDescription in der Dienstanwendung dürfen nach der Verwendung der OnOpening-Methode auf ServiceHostBase nicht geändert werden. Einige Member, wie die Credentials-Eigenschaft und die AddServiceEndpoint
-Methoden auf ServiceHostBase und ServiceHost, lösen eine Ausnahme aus, wenn sie nach diesem Zeitpunkt geändert werden. Andere erlauben Es Ihnen, sie zu ändern, aber das Ergebnis ist nicht definiert.
Ähnlich verhält es sich mit den ServiceEndpoint-Werten, die auf dem Client nach dem Aufruf von OnOpening auf ChannelFactory nicht geändert werden dürfen. Die Credentials Eigenschaft löst eine Ausnahme aus, wenn sie nach diesem Punkt geändert wurde. Die anderen Clientbeschreibungswerte können ohne Fehler geändert werden, aber das Ergebnis ist nicht definiert.
Ob es um den Dienst oder den Klienten geht, es wird empfohlen, die Beschreibung zu ändern, bevor Open aufgerufen wird.
Verwenden von Standardendpunkten
Wenn keine Endpunkte im Code oder in der Konfiguration angegeben sind, stellt die Laufzeit Standardendpunkte bereit, indem für jede Basisadresse für jeden vom Dienst implementierten Dienstvertrag ein Standardendpunkt hinzugefügt wird. Die Basisadresse kann im Code oder in der Konfiguration angegeben werden, und die Standardendpunkte werden hinzugefügt, wenn Open auf ServiceHost aufgerufen wird.
Wenn Endpunkte explizit bereitgestellt werden, können die Standardendpunkte weiterhin durch Aufrufen von AddDefaultEndpoints auf den ServiceHost hinzugefügt werden, bevor Open aufgerufen wird. Weitere Informationen zu Standardendpunkten, Bindungen und Verhalten finden Sie unter Vereinfachte Konfiguration und vereinfachte Konfiguration für WCF-Dienste.