Übersicht über die Metadatenarchitektur

Windows Communication Foundation (WCF) bietet eine umfangreiche Infrastruktur zum Exportieren, Veröffentlichen, Abrufen und Importieren von Dienstmetadaten. WCF-Dienste beschreiben mithilfe von Metadaten die Interaktion mit den Endpunkten des Diensts, sodass Tools, z. B. Svcutil.exe, automatisch Clientcode für den Zugriff auf den Dienst generieren können.

Die meisten der Typen, die die Metadaten-Infrastruktur von WCF bilden, befinden sich im System.ServiceModel.Description-Namespace.

WCF verwendet die ServiceEndpoint-Klasse, um Endpunkte in einem Dienst zu beschreiben. Sie können mit WCF Metadaten für Dienstendpunkte generieren oder Dienstmetadaten importieren, um ServiceEndpoint-Instanzen zu erzeugen.

WCF stellt die Metadaten für einen Dienst als Instanz des MetadataSet-Typs dar, dessen Struktur eng an das Metadaten-Serialisierungsformat gebunden ist, das in WS-MetadataExchange definiert ist. Der MetadataSet-Typ fasst die eigentlichen Dienstmetadaten, wie WSDL (Web Services Description Language)-Dokumente, XML-Schemadokumente oder WS-Richtlinienausdrücke, in einer Auflistung von MetadataSection-Instanzen zusammen. Jede System.ServiceModel.Description.MetadataSection-Instanz enthält einen bestimmten Metadaten-Dialekt und einen Bezeichner. Ein System.ServiceModel.Description.MetadataSection-Element kann die folgenden Elemente in seiner MetadataSection.Metadata-Eigenschaft enthalten:

System.ServiceModel.Description.MetadataReference-Instanzen zeigen auf einen anderen MEX (Metadata Exchange)-Endpunkt, und System.ServiceModel.Description.MetadataLocation-Instanzen zeigen mithilfe einer HTTP-URL auf ein Metadatendokument. WCF unterstützt die Verwendung von WSDL-Dokumenten zur Beschreibung von Dienstendpunkten, Dienstverträgen, Bindungen, Nachrichtenaustauschmustern, Nachrichten und Fehlermeldungen, die durch einen Dienst implementiert werden. Die vom Dienst verwendeten Datentypen werden in WSDL-Dokumenten mithilfe eines XML-Schemas beschrieben. Weitere Informationen finden Sie unter Schemaimport und -export. Sie können WCF zum Exportieren und Importieren von WSDL-Erweiterungen für Dienstverhalten, Vertragsverhalten und Bindungselemente verwenden, die die Funktionalität eines Diensts erweitern. Weitere Informationen finden Sie unter Exportieren von benutzerdefinierten Metadaten für eine WCF-Erweiterung.

Exportieren von Dienstmetadaten

In WCF ist der Metadatenexport der Prozess zum Beschreiben der Dienstendpunkte und zum Projizieren der Dienstendpunkte in eine parallele, standardisierte Darstellung, die Clients zur Nutzung des Diensts verwenden können. Mit einer Implementierung der abstrakten ServiceEndpoint-Klasse können Sie Metadaten aus MetadataExporter-Instanzen exportieren. Eine System.ServiceModel.Description.MetadataExporter-Implementierung generiert Metadaten, die in einer MetadataSet-Instanz gekapselt werden.

Die System.ServiceModel.Description.MetadataExporter-Klasse stellt ein Framework für die Generierung von Richtlinienausdrücken bereit, welche die Fähigkeiten und Anforderungen einer Endpunktbindung und die zugehörigen Vorgänge, Meldungen und Fehler beschreiben. Diese Richtlinienausdrücke werden in einer PolicyConversionContext-Instanz aufgezeichnet. Eine System.ServiceModel.Description.MetadataExporter-Implementierung kann diese Richtlinienausdrücke dann an die von ihr generierten Metadaten anfügen.

Der System.ServiceModel.Description.MetadataExporter ruft jedes System.ServiceModel.Channels.BindingElement-Objekt auf, das die IPolicyExportExtension-Schnittstelle in der Bindung eines ServiceEndpoint implementiert, wenn ein PolicyConversionContext-Objekt für die zu verwendende System.ServiceModel.Description.MetadataExporter-Implementierung erzeugt wird. Sie können neue Richtlinienassertionen exportieren, indem Sie die IPolicyExportExtension-Schnittstelle in Ihren benutzerdefinierten Implementierungen des BindingElement-Typs implementieren.

Der WsdlExporter-Typ stellt die Implementierung der abstrakten System.ServiceModel.Description.MetadataExporter-Klasse in WCF dar. Der WsdlExporter-Typ generiert WSDL-Metadaten mit angefügten Richtlinienausdrücken.

Um benutzerdefinierte WSDL-Metadaten oder WSDL-Erweiterungen für Endpunktverhalten, Vertragsverhalten oder Bindungselemente in einem Dienstendpunkt zu exportieren, können Sie die IWsdlExportExtension-Schnittstelle implementieren. Der WsdlExporter untersucht eine ServiceEndpoint-Instanz daraufhin, ob sie Bindungselemente, Vorgangsverhalten, Vertragsverhalten und Endpunktverhalten enthält, die beim Erzeugen eines WSDL-Dokuments die IWsdlExportExtension-Schnittstelle implementieren.

Veröffentlichen von Dienstmetadaten

WCF-Dienste veröffentlichen Metadaten, indem sie einen oder mehrere Metadatenendpunkte verfügbar machen. Durch die Veröffentlichung von Dienstmetadaten werden die Dienstmetadaten mithilfe standardisierter Protokolle, wie MEX und HTTP/GET-Anforderungen, zur Verfügung gestellt. Metadatenendpunkte ähneln anderen Dienstendpunkten insofern, als dass sie über eine Adresse, eine Bindung und einen Vertrag verfügen. Sie können einem Diensthost in der Konfiguration oder im Code Metadatenendpunkte hinzufügen.

Um Metadatenendpunkte für einen WCF-Dienst zu veröffentlichen, müssen Sie zunächst eine Instanz des ServiceMetadataBehavior-Dienstverhaltens zum Dienst hinzufügen. Durch das Hinzufügen einer System.ServiceModel.Description.ServiceMetadataBehavior-Instanz zu einem Dienst wird der Dienst um die Fähigkeit ergänzt, Metadaten zu veröffentlichen, indem er einen oder mehrere Metadatenendpunkt verfügbar macht. Sobald Sie das System.ServiceModel.Description.ServiceMetadataBehavior-Dienstverhalten hinzufügen, können Sie Metadatenendpunkte verfügbar machen, die das MEX-Protokoll unterstützen, oder Metadatenendpunkte, die auf die HTTP/GET-Anforderungen antworten.

Fügen Sie Dienstendpunkte zum Diensthost hinzu, die den Dienstvertrag "MetadataExchange" nutzen, um Metadatenendpunkte hinzuzufügen, die das MEX-Protokoll verwenden. WCF definiert die IMetadataExchange-Schnittstelle mit diesem Dienstvertragnamen. WS-MetadataExchange-Endpunkte oder MEX-Endpunkte können eine der vier Standardbindungen nutzen, die von den statischen Factorymethoden der MetadataExchangeBindings-Klasse verfügbar gemacht werden, sodass eine Anpassung an die von den WCF-Tools, wie „Svcutil.exe“, verwendeten Standardbindungen erreicht wird. Sie können MEX-Metadatenendpunkte auch mithilfe einer benutzerdefinierten Bindung konfigurieren.

Das ServiceMetadataBehavior verwendet einen System.ServiceModel.Description.WsdlExporter, um Metadaten für alle Dienstendpunkte in den Dienst zu exportieren. Weitere Informationen zum Exportieren von Metadaten aus einem Dienst finden Sie unter Exportieren und Importieren von Metadaten.

Das ServiceMetadataBehavior ergänzt den Diensthost, indem eine ServiceMetadataExtension-Instanz als Erweiterung dem Diensthost hinzugefügt wird. Die System.ServiceModel.Description.ServiceMetadataExtension stellt die Implementierung für die Metadaten bereit, die Protokolle veröffentlichen. Sie können darüber hinaus System.ServiceModel.Description.ServiceMetadataExtension verwenden, um die Metadaten des Diensts bei Laufzeit abzurufen, indem Sie auf die Metadata-Eigenschaft zugreifen.

Achtung

Wenn Sie der Konfigurationsdatei Ihrer Anwendung einen MEX-Endpunkt hinzufügen und anschließend dem Diensthost im Code das ServiceMetadataBehavior-Element hinzufügen, wird sinngemäß folgende Ausnahme ausgegeben:

System.InvalidOperationException: Der Vertragsname "IMetadataExchange" wurde nicht in der Liste der von Dienst "Service1" implementierten Verträge gefunden. Fügen Sie der Konfigurationsdatei oder dem ServiceHost ein ServiceMetadataBehavior-Element hinzu, um die Unterstützung des Vertrags zu aktivieren.

Fügen Sie der Konfigurationsdatei das ServiceMetadataBehavior-Element hinzu, oder fügen Sie den Endpunkt und das ServiceMetadataBehavior-Element im Code hinzu, um das Problem zu umgehen.

Ein Beispiel für das Hinzufügen des ServiceMetadataBehaviorElements zur Konfigurationsdatei einer Anwendung finden Sie unter Erste Schritte. Ein Beispiel für das Einfügen von ServiceMetadataBehavior Code finden Sie im Self-Host-Beispiel.

Achtung

Beim Veröffentlichen von Metadaten für einen Dienst, der zwei unterschiedliche Dienstverträge verfügbar macht, in denen jeweils eine Operation mit dem gleichen Namen enthalten ist, wird eine Ausnahme ausgelöst. Beispiel: Wenn ein Dienst einen Dienstvertrag namens "ICarService" mit einer Get(Car c)-Operation verfügbar macht und der gleiche Dienst einen Dienstvertrag namens "IBookService" mit einer Get(Book b)-Operation verfügbar macht, wird beim Erstellen der Metadaten für den Dienst eine Ausnahme ausgelöst oder eine Fehlermeldung angezeigt. Verwenden Sie eine der folgenden Vorgehensweisen, um dieses Problem zu umgehen:

  • Benennen Sie eine der Operationen um.
  • Legen Sie die Name-Eigenschaft auf einen anderen Namen fest.
  • Legen Sie einen der Namespaces der Operation mit der Namespace-Eigenschaft auf einen anderen Namespace fest.

Abrufen der Dienstmetadaten

WCF kann Dienstmetadaten mithilfe standardisierter Protokolle, wie z. B. WS-MetadataExchange- und HTTP, abrufen. Beide Protokolle werden vom MetadataExchangeClient-Typ unterstützt. Sie rufen Dienstmetadaten mit dem System.ServiceModel.Description.MetadataExchangeClient-Typ ab, indem Sie eine Adresse und eine optionale Bindung angeben. Bei der von einer System.ServiceModel.Description.MetadataExchangeClient-Instanz verwendeten Bindung kann es sich um eine der Standardbindungen aus der statischen MetadataExchangeBindings-Klasse, eine vom Benutzer angegebene Bindung oder eine aus einer Endpunktkonfiguration für den IMetadataExchange-Vertrag geladene Bindung handeln. Der System.ServiceModel.Description.MetadataExchangeClient kann auch HTTP-URL-Verweise auf Metadaten mit dem HttpWebRequest-Typ auflösen.

Standardmäßig wird eine System.ServiceModel.Description.MetadataExchangeClient-Instanz an eine einzelne ChannelFactoryBase-Instanz gebunden. Sie können die ChannelFactoryBase-Instanz, die von einem System.ServiceModel.Description.MetadataExchangeClient verwendet wird, durch Überschreiben der virtuellen GetChannelFactory-Methode ändern oder ersetzen. Ebenso können Sie die System.Net.HttpWebRequest-Instanz, die von einem System.ServiceModel.Description.MetadataExchangeClient zur Erstellung von HTTP/GET-Anforderungen verwendet wird, durch Überschreiben der virtuellen MetadataExchangeClient.GetWebRequest-Methode ändern oder ersetzen.

Sie können Dienstmetadaten mit WS-MetadataExchange- oder HTTP/GET-Anforderungen unter Verwendung des Tools Svcutil.exe und durch Angabe des //target:metadata-Switches und einer Adresse abrufen. Svcutil.exe lädt die Metadaten von der angegebenen Adresse herunter und speichert die Dateien auf dem Datenträger. Svcutil.exe verwendet intern eine System.ServiceModel.Description.MetadataExchangeClient-Instanz und lädt die MEX-Endpunktkonfiguration, deren Name mit dem Schema der an Svcutil.exe als Eingabe weitergegebenen Adresse übereinstimmt, aus der Anwendungskonfigurationsdatei, sofern vorhanden. Andernfalls verwendet Svcutil.exe standardmäßig eine der Bindungen, die durch den statischen MetadataExchangeBindings-Factorytyp definiert werden.

Importieren von Dienstmetadaten

In WCF wird beim Importieren von Metadaten eine abstrakte Darstellung eines Diensts oder seiner Komponenten aus dessen Metadaten generiert. WCF kann beispielsweise Instanzen von ServiceEndpoint, Binding oder ContractDescription aus einem WSDL-Dokument für einen Dienst importieren. Mit einer Implementierung der abstrakten MetadataImporter-Klasse können Sie Metadaten von Diensten in WCF importieren. Die Unterstützung für das Importieren von Metadatenformaten, die die Importlogik der WS-Richtlinie in WCF unterstützen, wird durch Typen implementiert, die von der System.ServiceModel.Description.MetadataImporter-Klasse abgeleitet sind.

Eine System.ServiceModel.Description.MetadataImporter-Implementierung sammelt die an die Dienstmetadaten angefügten Richtlinienausdrücke in einem PolicyConversionContext-Objekt. Der System.ServiceModel.Description.MetadataImporter verarbeitet die Richtlinien dann im Rahmen des Importvorgangs, indem er die Implementierungen der IPolicyImportExtension-Schnittstelle in der PolicyImportExtensions-Eigenschaft aufruft.

Sie können einen System.ServiceModel.Description.MetadataImporter um Unterstützung für den Import neuer Richtlinienassertionen erweitern, indem Sie Ihre eigene Implementierung der IPolicyImportExtension-Schnittstelle der PolicyImportExtensions-Auflistung in einer System.ServiceModel.Description.MetadataImporter-Instanz hinzufügen. Sie können stattdessen die Richtlinienimporterweiterung auch in der Konfigurationsdatei der Clientanwendung registrieren.

Der System.ServiceModel.Description.WsdlImporter-Typ stellt die Implementierung der abstrakten System.ServiceModel.Description.MetadataImporter-Klasse in WCF dar. Der System.ServiceModel.Description.WsdlImporter-Typ importiert WSDL-Metadaten mit angefügten Richtlinien, die in einem MetadataSet-Objekt zusammengefasst sind.

Um Unterstützung für das Importieren von WSDL-Erweiterungen hinzuzufügen, implementieren Sie die IWsdlImportExtension-Schnittstelle, und fügen Sie diese Implementierung der WsdlImportExtensions-Eigenschaft der System.ServiceModel.Description.WsdlImporter-Instanz hinzu. Der System.ServiceModel.Description.WsdlImporter kann auch Implementierungen der System.ServiceModel.Description.IWsdlImportExtension-Schnittstelle laden, die in der Clientkonfigurationsdatei registriert ist.

Dynamische Bindungen

Sie können die Bindung, die zum Erstellen eines Kanals zu einem Dienstendpunkt verwendet wird, dynamisch aktualisieren, wenn sich die Bindung für den Endpunkt ändert oder wenn Sie einen Kanal zu einem Endpunkt erstellen möchten, der den gleichen Vertrag verwendet, aber über eine andere Bindung verfügt. Sie können mithilfe der statischen MetadataResolver-Klasse zur Laufzeit Metadaten für Dienstendpunkte abrufen und importieren, die einen bestimmten Vertrag implementieren. Mit den importierten System.ServiceModel.Description.ServiceEndpoint-Objekten können Sie einen Client oder eine Kanalfactory für den gewünschten Endpunkt erstellen.

Siehe auch