Panoramica dell'architettura dei metadati

Windows Communication Foundation (WCF) fornisce un'infrastruttura profonda per l'esportazione, la pubblicazione, il recupero e l'importazione dei metadati del servizio. I servizi WCF utilizzano metadati per descrivere come interagire con gli endpoint del servizio affinché strumenti quali Svcutil.exe possano generare automaticamente il codice client per accedere al servizio.

La maggior parte dei tipi che costituiscono l'infrastruttura dei metadati di WCF risiede nello spazio dei nomi System.ServiceModel.Description.

WCF usa la classe ServiceEndpoint per descrivere endpoint in un servizio. È possibile utilizzare WCF per generare metadati per endpoint del servizio o importare metadati del servizio per generare istanze di ServiceEndpoint.

WCF rappresenta i metadati per un servizio come istanza del tipo MetadataSet, la cui struttura dipende strettamente dal formato di serializzazione dei metadati definito in WS-MetadataExchange. Il tipo MetadataSet raggruppa i metadati effettivi del servizio, ad esempio i documenti Web Services Description Language (WSDL), i documenti di XML Schema o le espressioni WS-Policy, come raccolta di istanze di MetadataSection. Ogni istanza di System.ServiceModel.Description.MetadataSection contiene un sottolinguaggio dei metadati specifici e un identificatore. Una System.ServiceModel.Description.MetadataSection può contenere gli elementi seguenti nella proprietà MetadataSection.Metadata:

Le istanze di System.ServiceModel.Description.MetadataReference puntano a un altro endpoint di scambio di metadati (MEX) e le istanze di System.ServiceModel.Description.MetadataLocation puntano a un documento di metadati utilizzando un URL HTTP. WCF supporta l'utilizzo di documenti WSDL per descrivere endpoint di servizio, contratti di servizio, associazioni, modelli di scambio di messaggi, messaggi e messaggi di errore implementati da un servizio. I tipi di dati utilizzati dal servizio sono descritti nei documenti WSDL utilizzando XML Schema. Per altre informazioni, vedere Importazione ed esportazione degli schemi. È possibile utilizzare WCF per esportare e importare estensioni WSDL per il comportamento del servizio, i comportamenti del contratto e gli elementi di associazione che estendono la funzionalità di un servizio. Per altre informazioni, vedere Esportazione di metadati personalizzati per un'estensione WCF.

Esportazione di metadati del servizio

In WCF, l'esportazione di metadati è il processo utilizzato per descrivere gli endpoint di un servizio e quindi proiettarli in una rappresentazione parallela standardizzata che i client possono utilizzare allo scopo di comprendere come utilizzare il servizio. Per esportare metadati da istanze di ServiceEndpoint, utilizzare un'implementazione della classe astratta MetadataExporter. Un'implementazione System.ServiceModel.Description.MetadataExporter genera metadati che sono incapsulati in un'istanza di MetadataSet.

La classe System.ServiceModel.Description.MetadataExporter fornisce un framework per la generazione di espressioni di criteri che descrivono le funzionalità e i requisiti di un'associazione di endpoint e le operazioni, i messaggi e gli errori pertinenti. Queste espressioni di criteri vengono acquisite in un'istanza di PolicyConversionContext. Un'implementazione di System.ServiceModel.Description.MetadataExporter può quindi collegare tali espressioni di criteri ai metadati che genera.

System.ServiceModel.Description.MetadataExporter chiama ogni System.ServiceModel.Channels.BindingElement che implementa l'interfaccia IPolicyExportExtension nell'associazione di un ServiceEndpoint durante la generazione di un oggetto PolicyConversionContext che deve essere utilizzato dall'implementazione di System.ServiceModel.Description.MetadataExporter. È possibile esportare nuove asserzioni di criteri implementando l'interfaccia IPolicyExportExtension nelle implementazioni personalizzate del tipo BindingElement.

Il tipo WsdlExporter è l'implementazione della classe astratta System.ServiceModel.Description.MetadataExporter inclusa con WCF. Il tipo WsdlExporter genera metadati WSDL con allegate le espressioni di criteri.

Per esportare metadati WSDL personalizzati o estensioni WSDL per i comportamenti degli endpoint, i comportamenti del contratto o elementi di associazione in un endpoint del servizio, è possibile implementare l'interfaccia IWsdlExportExtension. WsdlExporter cerca in un'istanza ServiceEndpoint elementi di associazione, comportamenti dell'operazione, comportamenti del contratto e comportamenti degli endpoint che implementano l'interfaccia IWsdlExportExtension in fase di generazione del documento WSDL.

Pubblicazione di metadati del servizio

I servizi WCF pubblicano i metadati tramite l'esposizione di uno o più endpoint dei metadati. La pubblicazione dei metadati del servizio li rende disponibili utilizzando i protocolli standard, ad esempio le richieste MEX e HTTP/GET. Gli endpoint dei metadati sono accomunati ad altri endpoint del servizio dal fatto di avere un indirizzo, un'associazione e un contratto. È possibile aggiungere endpoint dei metadati a un host del servizio nella configurazione o nel codice.

Per pubblicare endpoint dei metadati per un servizio WCF, è innanzitutto necessario aggiungere al servizio un'istanza del comportamento del servizio ServiceMetadataBehavior. L'aggiunta di un'istanza System.ServiceModel.Description.ServiceMetadataBehavior al servizio aggiunge a quest'ultimo la capacità di pubblicare metadati esponendo uno o più endpoint dei metadati. Dopo aver aggiunto il comportamento del servizio System.ServiceModel.Description.ServiceMetadataBehavior, è possibile esporre gli endpoint dei metadati che supportano il protocollo MEX o quelli che rispondono alle richieste HTTP/GET.

Per aggiungere endpoint dei metadati che utilizzano il protocollo MEX, aggiungere endpoint del servizio all'host del servizio che utilizza il contratto di servizio denominato IMetadataExchange. WCF definisce l'interfaccia IMetadataExchange con questo nome di contratto di servizio. Endpoint WS-MetadataExchange, o endpoint MEX, possono utilizzare una delle quattro associazioni predefinite che i metodi factory statici espongono sulla classe MetadataExchangeBindings in modo che corrispondano alle associazioni predefinite utilizzate dagli strumenti WCF, ad esempio Svcutil.exe. È inoltre possibile configurare gli endpoint dei metadati MEX utilizzando un'associazione personalizzata.

ServiceMetadataBehavior utilizza un oggetto System.ServiceModel.Description.WsdlExporter per esportare i metadati per tutti gli endpoint nel servizio. Per altre informazioni sull'esportazione di metadati da un servizio, vedere Esportazione e importazione di metadati.

ServiceMetadataBehavior aggiunge all'host del servizio un'istanza di ServiceMetadataExtension come estensione. System.ServiceModel.Description.ServiceMetadataExtension fornisce l'implementazione per i metadati che pubblicano protocolli. È inoltre possibile utilizzare System.ServiceModel.Description.ServiceMetadataExtension per ottenere i metadati del servizio in fase di esecuzione accedendo alla proprietà Metadata.

Attenzione

Se si aggiunge un endpoint MEX al file di configurazione dell'applicazione e quindi si tenta di aggiungere l'oggetto ServiceMetadataBehavior all'host del servizio nel codice, verrà generata l'eccezione seguente:

System.InvalidOperationException: Impossibile trovare il nome contratto 'IMetadataExchange' nell'elenco dei contratti implementati dal servizio Service1. Aggiungere un elemento ServiceMetadataBehavior al file di configurazione oppure direttamente a ServiceHost per abilitare il supporto per questo contratto.

Per risolvere il problema, aggiungere l'oggetto ServiceMetadataBehavior al file di configurazione oppure aggiungere sia l'endpoint che l'oggetto ServiceMetadataBehavior al codice.

Per un esempio di aggiunta dell'oggetto ServiceMetadataBehavior in un file di configurazione dell'applicazione, vedere Introduzione. Per un esempio di aggiunta dell'oggetto ServiceMetadataBehavior al codice, vedere l'esempio Servizio indipendente.

Attenzione

Quando si pubblicano metadati per un servizio che espone due contratti di servizio diversi in cui ciascuno contiene un'operazione dello stesso nome viene generata un'eccezione. Se ad esempio è presente un servizio che espone un contratto di servizio denominato ICarService con un'operazione Get(Car c) e lo stesso servizio espone un contratto di servizio denominato IBookService con un'operazione Get(Book b), viene generata un'eccezione o viene visualizzato un messaggio di errore durante la creazione dei metadati del servizio. Per risolvere il problema, effettuare una delle operazioni seguenti:

  • Rinominare una delle operazioni.
  • Impostare Name su un nome diverso.
  • Impostare uno degli spazi dei nomi delle operazioni su uno spazio dei nomi diverso, utilizzando la proprietà Namespace.

Recupero di metadati del servizio

In WCF è possibile recuperare i metadati del servizio utilizzando protocolli standard, ad esempio WS-MetadataExchange e HTTP. Entrambi questi protocolli sono supportati dal tipo MetadataExchangeClient. Per recuperare i metadati del servizio, utilizzare il tipo System.ServiceModel.Description.MetadataExchangeClient fornendo un indirizzo e un'associazione facoltativa. L'associazione utilizzata da un'istanza System.ServiceModel.Description.MetadataExchangeClient può essere una delle associazioni predefinite dalla classe statica MetadataExchangeBindings, un'associazione fornita dall'utente o un'associazione caricata dalla configurazione dell'endpoint per il contratto IMetadataExchange. System.ServiceModel.Description.MetadataExchangeClient può inoltre risolvere i riferimenti dell'URL HTTP ai metadati utilizzando il tipo HttpWebRequest.

Per impostazione predefinita, un'istanza di System.ServiceModel.Description.MetadataExchangeClient è collegata a una sola istanza di ChannelFactoryBase. È possibile modificare o sostituire l'istanza di ChannelFactoryBase utilizzata da System.ServiceModel.Description.MetadataExchangeClient eseguendo l'override del metodo virtuale GetChannelFactory. Analogamente, è possibile modificare o sostituire l'istanza di System.Net.HttpWebRequest utilizzata da System.ServiceModel.Description.MetadataExchangeClient per le richieste HTTP/GET eseguendo l'override del metodo virtuale MetadataExchangeClient.GetWebRequest.

È possibile recuperare i metadati del servizio utilizzando richieste WS-MetadataExchange o HTTP/GET mediante lo strumento Svcutil.exe e passando l'opzione /target:metadata e un indirizzo. Svcutil.exe scarica i metadati all'indirizzo specificato e salva i file su disco. Svcutil.exe utilizza un'istanza di System.ServiceModel.Description.MetadataExchangeClient internamente e carica una configurazione dell'endpoint MEX (dal file di configurazione dell'applicazione) il cui nome corrisponde allo schema dell'indirizzo passato a Svcutil.exe, se presente. In caso contrario, Svcutil.exe utilizza per impostazione predefinita una delle associazioni definite dal tipo di factory statico MetadataExchangeBindings.

Importazione di metadati del servizio

In WCF l'importazione dei metadati consiste nella generazione di una rappresentazione astratta di un servizio o dei relativi componenti a partire dai metadati del servizio. Ad esempio, WCF può importare istanze della classe ServiceEndpoint, della classe Binding o della classe ContractDescription da un documento WSDL di un servizio. Per importare i metadati del servizio in WCF è necessario utilizzare un'implementazione della classe astratta MetadataImporter. I tipi che derivano dalla classe System.ServiceModel.Description.MetadataImporter implementano il supporto per l'importazione dei formati di metadati che si basano sulla logica di importazione di WS-Policy di WCF.

Un'implementazione di System.ServiceModel.Description.MetadataImporter raccoglie le espressioni di criteri collegate ai metadati del servizio in un oggetto PolicyConversionContext. System.ServiceModel.Description.MetadataImporter elabora quindi i criteri come parte dell'importazione dei metadati chiamando le implementazioni dell'interfaccia IPolicyImportExtension nella proprietà PolicyImportExtensions.

È possibile aggiungere il supporto per importare nuove asserzioni di criteri in un System.ServiceModel.Description.MetadataImporter aggiungendo la propria implementazione dell'interfaccia IPolicyImportExtension alla raccolta PolicyImportExtensions in un'istanza System.ServiceModel.Description.MetadataImporter. In alternativa, è possibile registrare l'estensione di importazione dei criteri nel file di configurazione dell'applicazione client.

Il tipo System.ServiceModel.Description.WsdlImporter è l'implementazione della classe astratta System.ServiceModel.Description.MetadataImporter inclusa con WCF. Il tipo System.ServiceModel.Description.WsdlImporter importa metadati WSDL insieme ai relativi criteri allegati. Questi elementi vengono quindi raggruppati in un oggetto MetadataSet.

Per aggiungere il supporto per l'importazione di estensioni WSDL, implementare l'interfaccia IWsdlImportExtension, quindi aggiungere tale implementazione alla proprietà WsdlImportExtensions nell'istanza di System.ServiceModel.Description.WsdlImporter. È inoltre possibile utilizzare il tipo System.ServiceModel.Description.WsdlImporter per caricare implementazioni dell'interfaccia System.ServiceModel.Description.IWsdlImportExtension registrate nel file di configurazione dell'applicazione client.

Associazioni dinamiche

È possibile aggiornare dinamicamente l'associazione utilizzata per creare un canale per un endpoint del servizio nel caso in cui l'associazione per l'endpoint cambi o si desideri creare un canale per un endpoint che utilizza lo stesso contratto ma ha un'associazione diversa. È possibile utilizzare la MetadataResolver classe statica per recuperare e importare metadati in fase di esecuzione per endpoint del servizio che implementano un contratto specifico. È quindi possibile utilizzare gli oggetti System.ServiceModel.Description.ServiceEndpoint importati per creare un client o una channel factory per l'endpoint desiderato.

Vedi anche