Modifica di messaggi SOAP utilizzando estensioni SOAP

Questo argomento è specifico di una tecnologia legacy. Servizi Web XML e client di servizi Web XML devono essere creati attualmente tramite Windows Communication Foundation.

Le estensioni SOAP consentono agli sviluppatori di arricchire le funzionalità di un servizio Web modificando i messaggi SOAP inviati e ricevuti da un servizio Web o da un client del servizio Web. Ad esempio, è possibile implementare un algoritmo di crittografia o di compressione da eseguire con un servizio Web esistente.

Per comprendere le modalità di funzionamento di un'estensione SOAP, è utile innanzi tutto capire la durata di un servizio Web. Per ulteriori informazioni, vedere Anatomia del ciclo di vita di un servizio Web XML.

Nell'illustrazione seguente sono delineate le fasi principali di una chiamata da un client a un servizio Web.

Ciclo di vita dei servizi Web XML

Nel corso delle varie fasi, il .NET Framework provvede a serializzare e deserializzare il codice XML sul computer del servizio Web e sul computer client. È possibile inserire un'estensione SOAP nell'infrastruttura allo scopo di verificare o modificare i messaggi SOAP prima e dopo ciascuna di queste fasi di serializzazione e deserializzazione. Ad esempio, un'estensione SOAP di crittografia potrebbe crittografare la parte XML del messaggio SOAP dopo che il .NET Framework ha serializzato gli argomenti del client, e quindi decrittografare il messaggio SOAP sul server Web prima che il messaggio SOAP sia deserializzato dal .NET Framework. Queste fasi, in cui un'estensione SOAP potrebbe verificare o modificare il messaggio SOAP, sono definite nell'enumerazione SoapMessageStage. In questo caso, l'estensione SOAP sta implementando la crittografia in fase di AfterSerialize e la decrittografia in fase di BeforeDeserialize.

In genere, quando un'estensione SOAP modifica il contenuto di un messaggio SOAP, le modifiche devono essere eseguite sia nel client che nel server. Ovvero, se un'estensione SOAP deve essere eseguita sul client per la crittografia del messaggio SOAP, un'estensione SOAP corrispondente deve decrittografare il messaggio SOAP sul server. Se il messaggio SOAP non viene decrittografato, l'infrastruttura ASP.NET non è in grado di deserializzare il messaggio SOAP in un oggetto.

Naturalmente, un'estensione SOAP che non modifica il messaggio SOAP, ad esempio se registra semplicemente i messaggi SOAP, può essere in esecuzione solo sul client o sul server. In questo caso, il destinatario riceve lo stesso messaggio SOAP che avrebbe ricevuto con un'estensione SOAP non in esecuzione e l'infrastruttura ASP.NET può deserializzare il messaggio SOAP. Inoltre, se l'estensione SOAP non modifica il messaggio SOAP in modo da rendere impossibile la deserializzazione, non è necessario che l’estensione SOAP sia in esecuzione sia sul client che sul server.

Estensione della classe SOAPExtension

Per implementare un’estensione SOAP, occorre derivare una classe dalla classe SoapExtension. Esistono tre metodi della classe SOAPExtension che dovrebbero, o devono, essere implementati:

Le modalità di implementazione di questi metodi sono spiegate nella procedura dettagliata relativa alla modifica di messaggi SOAP utilizzando estensioni SOAP.

Viene passato un oggetto Stream al metodo ChainStream, che restituisce un oggetto Stream. Durante l’esecuzione dell'estensione SOAP e la modifica del messaggio SOAP nel corso di ogni SoapMessageStage, un'estensione SOAP dovrebbe leggere dallo Stream passato in ChainStream e scrivere nello Stream restituito da ChainStream. Pertanto, all’interno del metodo ChainStream, è importante assegnare entrambi i riferimenti Stream alle variabili membro.

La classe derivante da SoapExtension utilizza i metodi GetInitializer e Initialize per inizializzare dati interni, in base al servizio Web o al metodo del servizio Web al quale è applicata. Ad esempio, un'estensione SOAP che registra il messaggio SOAP in transito da e verso un metodo di servizio Web potrebbe inizializzare il nome di un file per salvare le informazioni di registrazione (in base al nome del servizio Web o del metodo del servizio Web con il quale l'estensione SOAP è in esecuzione).

Il momento in cui l'infrastruttura dei servizi Web chiama il metodo GetInitializer e quali parametri vengono passati al metodo dipendono dalla configurazione dell'estensione SOAP, secondo le modalità seguenti:

  • Se l'estensione SOAP è configurata utilizzando un attributo, GetInitializer è chiamato dall'infrastruttura dei servizi Web la prima volta che si accede al metodo method di un servizio Web.

  • Se l'estensione SOAP è configurata in un file di configurazione, GetInitializer è chiamato dall'infrastruttura dei servizi Web soltanto la prima volta che si accede all’intero servizio Web.

L'infrastruttura dei servizi Web conserva in memoria l'oggetto restituito dal metodo GetInitializer. Quindi ogni volta che l'estensione SOAP viene eseguita con quel servizio Web o metodo del servizio Web, l'infrastruttura passa l'oggetto di inizializzazione al metodo Initialize.

L’estensione dell’elaborazione oltre l'elaborazione SOAP standard viene eseguita dal metodo ProcessMessage. Ogni volta che l’infrastruttura di servizi Web esegue la chiamata a ProcessMessage, viene passata (come argomento) un'istanza di una classe derivata da SoapMessage che contiene informazioni sul messaggio SOAP relative a quella fase particolare. Se l’estensione SOAP è in esecuzione con un servizio Web, viene passato un oggetto SoapServerMessage. Se l’estensione SOAP è in esecuzione con un client del servizio Web, viene passato un oggetto SoapClientMessage.

Estensioni SOAP ed eccezioni

Le estensioni SOAP non devono mai generare eccezioni. Tuttavia, possono aggiungere informazioni sulle eccezioni alla proprietà Exception sull'oggetto SoapMessage passato nel metodo ProcessMessage.

Le estensioni SOAP possono inoltre agire in qualità di gestori di eccezioni per l’intera applicazione utilizzando la stessa funzionalità per intercettare tutte le eccezioni per le quali l’estensione SOAP è stata installata all’interno dell’applicazione e per compiere altre operazioni come la modifica dell'errore SOAP restituito.

Ordine in cui sono richiamati i metodi delle estensioni SOAP

Ora che sono stati analizzati i metodi di cui un'estensione SOAP esegue l'override, è possibile esaminare il momento in cui l'infrastruttura dei servizi Web richiama i metodi dell'estensione SOAP durante l’invocazione del metodo di un servizio Web. I passaggi seguenti presuppongono che l'estensione SOAP sia in esecuzione sul client e sul server. Se l'estensione SOAP non è in esecuzione sul client e sul server, i passaggi associati all'estensione SOAP in esecuzione su ciascuno di essi saranno ignorati dal .NET Framework.

Il lato client prepara un messaggio di richiesta

  1. Un client richiama un metodo sulla classe proxy.

  2. Una nuova istanza dell'estensione SOAP viene creata sul client.

  3. Se questa è la prima volta che l’estensione SOAP viene eseguita con il servizio Web sul client, il metodo GetInitializer viene richiamato sull'estensione SOAP in esecuzione sul client.

  4. Viene richiamato il metodo Initialize.

  5. Viene richiamato il metodo ChainStream.

  6. Viene richiamato il metodo ProcessMessage con SoapMessageStage impostato su BeforeSerialize.

  7. ASP.NET sul computer client serializza gli argomenti del metodo del servizio Web in codice XML.

  8. Viene richiamato il metodo ProcessMessage con SoapMessageStage impostato su AfterSerialize.

  9. ASP.NET sul computer client invia il messaggio SOAP sulla rete al server Web che ospita il servizio Web.

Il lato server riceve un messaggio di richiesta e prepara una risposta

  1. ASP.NET sul server Web riceve il messaggio SOAP.

  2. Una nuova istanza dell'estensione SOAP viene creata sul server Web.

  3. Sul server Web, se questa è la prima volta che l’estensione SOAP viene eseguita con il servizio Web dal lato server, viene richiamato il metodo GetInitializer sull'estensione SOAP in esecuzione sul server.

  4. Viene richiamato il metodo Initialize.

  5. Viene richiamato il metodo ChainStream.

  6. Viene richiamato il metodo ProcessMessage con SoapMessageStage impostato su BeforeDeserialize.

  7. ASP.NET deserializza gli argomenti all'interno del codice XML.

  8. Viene richiamato il metodo ProcessMessage con SoapMessageStage impostato su AfterDeserialize.

  9. Passando gli argomenti deserializzati, ASP.NET crea una nuova istanza della classe che implementa il servizio Web e richiama il metodo del servizio Web. L’oggetto risiede nello stesso computer del server Web.

  10. Il metodo del servizio Web esegue il codice e in seguito imposta il valore restituito ed eventuali parametri out.

  11. Viene richiamato il metodo ProcessMessage con SoapMessageStage impostato su BeforeSerialize.

  12. ASP.NET sul server Web serializza il valore restituito e i parametri out in XML.

  13. Viene richiamato il metodo ProcessMessage con SoapMessageStage impostato su AfterSerialize.

  14. ASP.NET invia sulla rete il messaggio SOAP di risposta al client del servizio Web.

Il lato client riceve un messaggio di risposta

  1. ASP.NET sul computer client riceve il messaggio SOAP.

  2. Viene richiamato il metodo ProcessMessage con SoapMessageStage impostato su BeforeDeserialize.

  3. ASP.NET deserializza il codice XML nel valore restituito ed eventuali i parametri out.

  4. Viene richiamato il metodo ProcessMessage con SoapMessageStage impostato su AfterDeserialize.

  5. ASP.NET passa il valore restituito ed eventuali parametri out all'istanza della classe proxy.

  6. Il client riceve il valore restituito ed eventuali parametri out.

Implementazione dell'estensione SOAP

Ci sono due modalità per eseguire un'estensione SOAP su un'applicazione server o client. Primo, è possibile configurare l'applicazione per eseguire l'estensione. Per configurare l'estensione SOAP in modo che sia eseguita per tutti i metodi Web su tutti i servizi Web, specialmente una radice virtuale, modificare la sezione Elemento <soapExtensionTypes> contenuta nel file Web.config. Il codice seguente mostra che il valore dell'attributo di type deve essere su una riga e deve includere il nome completo dell'estensione, oltre a versione, impostazioni cultura e token di chiave pubblica dell'assembly firmato.

<configuration>
 <system.web>
    <webServices>
      <soapExtensionTypes>
        <add type="Contoso.MySoapExtension, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
priority="1" group="0"/>
        </soapExtensionTypes>
    </webServices>
  </system.web>
</configuration>

Secondo, è possibile creare un attributo personalizzato che viene applicato a un metodo del servizio Web. Per creare l'attributo personalizzato, creare una classe che deriva da SoapExtensionAttribute. Per informazioni dettagliate sulla creazione di un attributo personalizzato, vedere Procedura: implementare un'estensione SOAP. Per ulteriori informazioni sulla creazione di attributi personalizzati, vedere la sezione relativa alla creazione di attributi personalizzati.

esw638yk.note(it-it,VS.100).gifNota:
In caso di implementazione di un'estensione SOAP, è possibile che si verifichi un tentativo di attacco Denial of Service (DOS) se l'estensione utilizza una classe XmlTextReader per leggere il flusso di dati. Un modo per impedire tale attacco è di verificare che la proprietà ProhibitDtd sia impostata su true.

Priorità e gruppi di priorità

Utilizzando gli attributi o la configurazione, è possibile assegnare alle estensioni SOAP una priorità che consente di determinare l'ordine relativo di esecuzione quando più estensioni SOAP sono configurate per essere eseguite con un metodo del servizio Web XML. Maggiore è la priorità assegnata a un'estensione SOAP, più immediato è il momento della sua esecuzione sul messaggio SOAP inviato o ricevuto sulla rete. Le estensioni SOAP appartengono a uno di tre gruppi di priorità. All'interno di ogni gruppo, la proprietà priority distingue ogni membro. Minore è la proprietà priority, maggiore risulterà la priorità relativa (0 è il valore più elevato).

I tre gruppi di priorità relativa per le estensioni SOAP sono: le estensioni SOAP configurate utilizzando un attributo e le estensioni SOAP specificate nel file di configurazione con l'impostazione di group pari a 0 o 1. Le priorità sono ordinate secondo la seguente modalità:

  • Gruppo di priorità superiore: le estensioni SOAP configurate utilizzando un file di configurazione con l'impostazione di group pari a 0.

  • Gruppo di priorità media: le estensioni SOAP configurate utilizzando un attributo.

  • Gruppo di priorità inferiore: le estensioni SOAP configurate utilizzando un file di configurazione con l'impostazione di group pari a 1.

L'esempio di codice seguente è un file di configurazione che specifica che l'estensione SOAP Logger.LoggerExtension è in esecuzione all'interno del gruppo di priorità relativa 0 e ha una priorità 1.

<configuration>
 <system.web>
   <webServices>
     <soapExtensionTypes>
      <add type="Logger.LoggerExtension,logger"
           priority="1"
           group="0" />
     </soapExtensionTypes>
    </webServices>
 </system.web>
</configuration>

Vedere anche

Attività

Procedura: implementare un'estensione SOAP

Riferimento

SoapExtension
SoapExtensionAttribute
SoapMessageStage
LogicalMethodInfo

Concetti

Modifica di messaggi SOAP utilizzando estensioni SOAP
Anatomia del ciclo di vita di un servizio Web XML
Compilazione di client dei servizi Web XML

Altre risorse

Configuring Applications
Creare servizi Web XML mediante ASP.NET