Utilizzo di intestazioni SOAP

La comunicazione con un metodo di servizio Web XML tramite SOAP segue un formato standard. Una parte di questo formato è rappresentata dai dati codificati in un documento XML. Il documento XML comprende un tag Envelope di primo livello, che a sua volta comprende un elemento Body richiesto e un elemento Header facoltativo. L'elemento Body comprende i dati specifici di un messaggio. L'elemento Header facoltativo può contenere informazioni aggiuntive che non sono direttamente correlate al messaggio specifico. Ogni elemento figlio dell'elemento Header viene denominato intestazione SOAP.

Sebbene le intestazioni SOAP possano contenere dati relativi al messaggio, poiché la specifica SOAP non definisce in modo esplicito il contenuto di un'intestazione SOAP, di norma contengono informazioni elaborate dall'infrastruttura all'interno di un server Web. Un'intestazione SOAP può ad esempio essere utilizzata per fornire informazioni sul routing per il messaggio SOAP all'interno dell'intestazione SOAP.

Definizione ed elaborazione di intestazioni SOAP

I servizi Web XML creati con ASP.NET consentono di definire e modificare le intestazioni SOAP. La definizione di un'intestazione SOAP viene eseguita definendo una classe che rappresenta i dati in una determinata intestazione SOAP e derivandola dalla classe SoapHeader.

Per definire una classe che rappresenta un'intestazione SOAP

  1. Creare una classe derivandola dalla classe SoapHeader con un nome che corrisponde all'elemento di primo livello per l'intestazione SOAP.

    public class MyHeader : SoapHeader
    [Visual Basic]
    Public Class MyHeader : Inherits SoapHeader
    
  2. Aggiungere campi o proprietà pubbliche che corrispondono ai nomi e ai rispettivi tipi di dati per ogni elemento nell'intestazione SOAP.

    In base all'intestazione SOAP seguente, ad esempio, la classe successiva definisce una classe che rappresenta un'intestazione SOAP.

    public class MyHeader : SoapHeader
    {
       public DateTime Created;
       public long Expires;
    } 
    [Visual Basic]
    Public Class MyHeader
      Inherits SoapHeader
        Public Created As DateTime
        Public Expires As Long
    End Class
    

Per elaborare intestazioni SOAP all'interno di un servizio Web XML

  1. Aggiungere un membro pubblico alla classe che implementa il servizio Web XML del tipo che rappresenta l'intestazione SOAP.

    [WebService(Namespace="http://www.contoso.com")]
    public class MyWebService 
    {
        // Add a member variable of the type deriving from SoapHeader.
        public MyHeader timeStamp;
    [Visual Basic]
    <WebService(Namespace:="http://www.contoso.com")> _
    Public Class MyWebService
        ' Add a member variable of the type deriving from SoapHeader.
        Public TimeStamp As MyHeader
    
  2. Applicare un attributo SoapHeader a ogni metodo di servizio Web XML che elaborerà l'intestazione SOAP. Impostare la proprietà MemberName dell'attributo SoapHeader sul nome della variabile membro creata durante il primo passaggio.

    [WebMethod]
    [SoapHeader("timeStamp")]
    public void MyWebMethod()
    [Visual Basic]
    <WebMethod, SoapHeader("TimeStamp")> _ 
    Public Sub MyWebMethod()
    
  3. All'interno di ogni metodo di servizio Web XML a cui è applicato l'attributo SoapHeader, accedere alla variabile membro creata durante il primo passaggio per elaborare i dati inviati nell'intestazione SOAP.

    [WebMethod]
    [SoapHeader("timeStamp",            Direction=SoapHeaderDirection.InOut)]
    public string MyWebMethod() 
    {
      // Verify that the client sent the SOAP Header.
      if (timeStamp == null)
      {
         timeStamp = new MyHeader();
      }
      // Set the value of the SoapHeader returned
      // to the client.
      timeStamp.Expires = 60000;
      timeStamp.Created = DateTime.UtcNow;
    
      return "Hello World";
    }
    [Visual Basic]
    <WebMethod,SoapHeader("TimeStamp", _                      Direction:=SoapHeaderDirection.InOut)> _ 
    Public Function MyWebMethod() As String
       ' Verify that the client sent the SOAP Header. 
       If (TimeStamp Is Nothing) Then
          TimeStamp = New MyHeader
       End If
    
       ' Set the value of the SoapHeader returned
       ' to the client.
       TimeStamp.Expires = 60000
       TimeStamp.Created = DateTime.UtcNow
    
       Return "Hello World"
    End Function
    

Nell'esempio di codice che segue viene mostrato come definire ed elaborare un'intestazione SOAP in un servizio Web XML creato con ASP.NET. Nel servizio Web XML MyWebService è inclusa una variabile membro denominata timeStamp, il cui tipo è derivato da SoapHeader (MyHeader), impostata sulla proprietà MemberName dell'attributo SoapHeader. Al metodo MyWebMethod del servizio Web XML è inoltre applicato un attributo SoapHeader impostato su myHeaderMemberVariable. Nel metodo MyWebMethod del servizio Web XML si accede a myHeaderMemberVariable per impostare il valore degli elementi XML Created ed Expires dell'intestazione SOAP.

<%@ WebService Language="C#" Class="MyWebService" %>
using System;
using System.Web.Services;
using System.Web.Services.Protocols;

// Define a SOAP header by deriving from the SoapHeader class.
public class MyHeader : SoapHeader
{
   public DateTime Created;
   public long Expires;
}

[WebService(Namespace="http://www.contoso.com")]
public class MyWebService : System.Web.Services.WebService
{
   // Add a member variable of the type deriving from SoapHeader.
   public MyHeader timeStamp;

   // Apply a SoapHeader attribute.
   [WebMethod]
   [SoapHeader("timeStamp", Direction=SoapHeaderDirection.InOut)]
   public string HelloWorld()
   {
      if (timeStamp == null)
         timeStamp = new MyHeader();
         
      timeStamp.Expires = 60000;
      timeStamp.Created = DateTime.UtcNow;
         
      return "Hello World";
   }
} 
[Visual Basic]
<%@ WebService Language="VB" Class="MyWebService" %>
Imports System
Imports System.Web.Services
Imports System.Web.Services.Protocols

' Define a SOAP header by deriving from the SoapHeader class.
Public Class MyHeader
    Inherits SoapHeader
    Public Created As DateTime
    Public Expires As Long
End Class

<WebService(Namespace:="http://www.contoso.com")> _
Public Class MyWebService
    Inherits System.Web.Services.WebService

    ' Add a member variable of the type deriving from SoapHeader.
    Public timeStamp As MyHeader

    ' Apply a SoapHeader attribute.
    <WebMethod(), _
     SoapHeader("timeStamp", Direction:=SoapHeaderDirection.InOut)> _
    Public Function HelloWorld() As String

        If (timeStamp Is Nothing) Then
            timeStamp = New MyHeader
        End If

        timeStamp.Expires = 60000
        timeStamp.Created = DateTime.UtcNow

        Return "Hello World"
    End Function
End Class
In the previous example, a SOAP response is returned to the client with the Expires element set to 60000 (number of milliseconds, so 1 minute) and the Created element to the current time in coordinated universal time.  That is, the following SOAP response is sent to the client.
<? xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <MyHeader xmlns="http://www.contoso.com">
      <Created>dateTime</Username>
      <Expires>long</Password>
    </MyHeader>
  </soap:Header>
  <soap:Body>
    <HelloWorldResponse xmlns="http://www.contoso.com" />
  </soap:Body>
</soap:Envelope>

Generazione di un client per l'elaborazione di intestazioni SOAP

Un client di servizi Web XML può inviare e ricevere intestazioni SOAP durante la comunicazione con un servizio Web XML. Quando viene generata una classe proxy per un servizio Web XML che prevede o restituisce intestazioni SOAP utilizzando l'utilità Wsdl.exe, la classe proxy comprende informazioni sulle intestazioni SOAP. In particolare, la classe proxy dispone di variabili membro che rappresentano le intestazioni SOAP correlate a quelle trovate nel servizio Web XML. La classe proxy dispone inoltre di definizioni per le classi corrispondenti che rappresentano l'intestazione SOAP. Le classi proxy generate per il servizio Web XML precedente, ad esempio, disporranno di una variabile membro di tipo MyHeader e di una definizione per la classe MyHeader. Per ulteriori informazioni sulla creazione di una classe proxy, vedere Creazione di un proxy di servizio Web XML.

Nota: se il servizio Web XML definisce le variabili membro che rappresentano le intestazioni SOAP di tipo SoapHeader o SoapUnknownHeader anziché una classe derivata da SoapHeader, una classe proxy non disporrà di alcuna informazione sull'intestazione SOAP.

Per elaborare le intestazioni SOAP in un client del servizio Web XML

  1. Creare una nuova istanza della classe che rappresenta l'intestazione SOAP.

    Dim header As MyHeader = New MyHeader()
    [C#]
    MyHeader header = new MyHeader();
    
  2. Inserire i valori per l'intestazione SOAP.

    header.Expires = 60000
    header.Created = DateTime.UtcNow
    [C#]
    header.Expires = 60000;
    header.Created = DateTime.UtcNow;
    
  3. Creare una nuova istanza della classe proxy.

    Dim proxy As MyWebService = New MyWebService()
    [C#]
    MyWebService proxy = new MyWebService();
    
  4. Assegnare l'oggetto intestazione SOAP alla variabile membro della classe proxy che rappresenta l'intestazione SOAP.

    proxy.MyHeaderValue = header
    [C#]
    proxy.MyHeaderValue = header;
    
  5. Chiamare il metodo sulla classe proxy che comunica con il metodo di servizio Web XML.

    La parte dell'intestazione SOAP relativa alla richiesta SOAP inviata al servizio Web XML comprenderà il contenuto dei dati memorizzati nell'oggetto di intestazione SOAP.

    Dim results as String = proxy.MyWebMethod()
    [C#]
    string results = proxy.MyWebMethod();
    

Nell'esempio di codice seguente viene illustrato come passare un'intestazione SOAP da un client a un servizio Web XML.

<%@ Page Language="VB" %>

<asp:Label id="ReturnValue" runat="server" />
<script runat=server language=VB>

 Sub Page_Load(o As Object, e As EventArgs)

  Dim header As MyHeader = New MyHeader()  ' Populate the values of the SOAP header.   header.Expires = 60000   header.Created = DateTime.UtcNow

  ' Create a new instance of the proxy class.
  Dim proxy As MyWebService = New MyWebService()
  
  ' Add the MyHeader SOAP header to the SOAP request.  proxy.MyHeaderValue = header

  ' Call the method on the proxy class that communicates
  ' with your XML Web service method.
  Dim results as String = proxy.MyWebMethod()

  ' Display the results of the method in a label.
  ReturnValue.Text = results

 End Sub
</script>
[C#]
<%@ Page Language="C#" %>

<asp:Label id="ReturnValue" runat="server" />
<script runat=server language=c#>

 void Page_Load(Object o, EventArgs e)
 {

  MyHeader header = new MyHeader();  // Populate the values of the SOAP header.  header.Expires = 60000;  header.Created = DateTime.UtcNow;

  // Create a new instance of the proxy class.
  MyWebService proxy = new MyWebService();
  
  // Add the MyHeader SOAP header to the SOAP request.  proxy.MyHeaderValue = header;

  // Call the method on the proxy class that communicates 
  // with your XML Web service method.
  string results = proxy.MyWebMethod();

  // Display the results of the method in a label.
  ReturnValue.Text = results;
 }
</script>

Modifica dei destinatari di intestazioni SOAP

Per impostazione predefinita, quando un attributo SoapHeader viene applicato a un metodo di servizio Web XML, le intestazioni SOAP vengono inviate a un metodo di servizio Web XML tramite un client del servizio Web XML. Un'intestazione SOAP, tuttavia, può essere restituita al client del servizio Web XML anche tramite un metodo di servizio Web XML. Può inoltre essere inviata in entrambi modi. L'impostazione della proprietà Direction di un attributo SoapHeader applicato a un metodo di servizio Web XML controlla il destinatario dell'intestazione SOAP. La proprietà Direction è di tipo SoapHeaderDirection e dispone di quattro valori: In, Out, InOut e Fault. Questi valori si riferiscono rispettivamente al destinatario (se si tratta del server del servizio Web XML), al client, sia al client che al server del servizio Web XML oppure al caso in cui l'intestazione SOAP viene inviata al client quando il servizio Web XML genera un'eccezione.

Nota: con la versione 1.0 di .NET Framework SDK il valore Fault non è supportato.

Per modificare il destinatario dell'intestazione SOAP

  1. Definire l'intestazione SOAP.

    public class MyHeader : SoapHeader
    {
       public DateTime Created;
       public long Expires;
    } 
    [Visual Basic]
    Public Class MyHeader
      Inherits SoapHeader
        Public Created As DateTime
        Public Expires As Long
    End Class
    
  2. Aggiungere una variabile membro alla classe che implementa il servizio Web XML.

    [WebService(Namespace="http://www.contoso.com")]
    public class MyWebService : WebService
    {
        public MyHeader myOutHeader;
    [Visual Basic]
    <WebService(Namespace:="http://www.contoso.com")> _
    Public Class MyWebService  
      Inherits WebService
        Public myOutHeader As MyHeader
    
  3. Applicare un attributo SoapHeader a ogni metodo di servizio Web XML che elabora l'intestazione SOAP. Impostare la proprietà Direction su ogni destinatario desiderato, utilizzando l'enumerazione SoapHeaderDirection. Nell'esempio seguente il client del servizio Web XML viene definito come destinatario tramite l'impostazione di Direction su SoapHeaderDirection.Out.

    [WebMethod]
    [SoapHeader("myOutHeader",Direction=SoapHeaderDirection.Out)]
    [Visual Basic]
    <WebMethod, _
     SoapHeader("myOutHeader",Direction:=SoapHeaderDirection.Out)>
    
  4. Elaborare o impostare l'intestazione SOAP in base al destinatario. Nell'esempio di codice seguente vengono impostati i valori dell'intestazione SOAP, poiché il destinatario è il client del servizio Web XML.

    // Set the Time the SOAP message expires.
    myOutHeader.Expires = 60000;
    myOutHeader.Created = DateTime.UtcNow;
    [Visual Basic]
    ' Set the Time the SOAP message expires.
    myOutHeader.Expires = 60000
    myOutHeader.Created = DateTime.UtcNow
    

Nell'esempio di codice seguente viene definita un'intestazione SOAP MyHeader inviata dal metodo di servizio Web XML al client.

<%@ WebService Language="C#" Class="MyWebService" %>
using System;
using System.Web.Services;
using System.Web.Services.Protocols;

// Define a SOAP header by deriving from the SoapHeader class.
public class MyHeader : SoapHeader
{
   public DateTime Created;
   public long Expires;
} 

[WebService(Namespace="http://www.contoso.com")]
public class MyWebService : WebService
{
    public MyHeader myOutHeader;
 
    [WebMethod]
    [SoapHeader("myOutHeader",Direction=SoapHeaderDirection.Out)]
    public void MyOutHeaderMethod() 
    {
      // Set the time the SOAP message expires.
      myOutHeader.Expires = 60000;
      myOutHeader.Created = DateTime.UtcNow;
    }
}
[Visual Basic]
<%@ WebService Language="VB" Class="MyWebService" %>
Imports System
Imports System.Web.Services
Imports System.Web.Services.Protocols

' Define a SOAP header by deriving from the SoapHeader class.
Public Class MyHeader
  Inherits SoapHeader
    Public Created As DateTime
    Public Expires As Long
End Class

<WebService(Namespace:="http://www.contoso.com")> _
Public Class MyWebService 
  Inherits WebService
    Public myOutHeader As MyHeader 
    
    <WebMethod, _
     SoapHeader("myOutHeader",Direction:=SoapHeaderDirection.Out)> _
    Public Sub MyOutHeaderMethod()
         ' Set the time the SOAP message expires.
         myOutHeader.Expires = 60000
         myOutHeader.Created = DateTime.UtcNow
    End Sub
End Class

Gestione di intestazioni SOAP sconosciute

Un client del servizio Web XML può inviare una richiesta SOAP con un'intestazione SOAP a un metodo di servizio Web XML la cui richiesta potrebbe non essere stata definita in modo esplicito dal servizio Web XML. In questo caso, è importante determinare se la semantica dell'intestazione SOAP viene compresa ed elaborata, poiché la specifica SOAP stabilisce che venga generata un'eccezione quando le intestazioni SOAP dispongono di un attributo mustUnderstand impostato su true. Per ulteriori informazioni sulla gestione delle intestazioni SOAP richieste dal client, vedere Gestione di intestazioni SOAP richieste da un client del servizio Web XML.

Per gestire intestazioni SOAP sconosciute da un client del servizio Web XML

  1. Aggiungere alla classe che implementa il servizio Web XML una variabile membro di tipo SoapUnknownHeader, SoapHeader o matrice di uno dei due, per gestire più intestazioni SOAP sconosciute.

    La dichiarazione del tipo come matrice o singola istanza di SoapUnknownHeader presenta l'ulteriore vantaggio che SoapUnknownHeader dispone di una proprietà Element. La proprietà Element è di tipo XmlElement e rappresenta il documento XML per l'elemento Header della richiesta SOAP o della risposta SOAP. Un metodo di servizio Web XML può quindi determinare il nome dell'intestazione SOAP, insieme ai dati passati dall'intestazione SOAP, interrogando la proprietà Element.

    public class MyWebService {
        public SoapUnknownHeader[] unknownHeaders;
    [Visual Basic]
    Public Class MyWebService
        Public unknownHeaders() As SoapUnknownHeader
    
  2. Applicare un attributo SoapHeader a ogni metodo di servizio Web XML che elaborerà ciascuna intestazione SOAP sconosciuta.

        [WebMethod]
        [SoapHeader("unknownHeaders")]
        public string MyWebMethod()
    [Visual Basic]
        <WebMethod, _
         SoapHeader("unknownHeaders") > _
        Public Function MyWebMethod() As String
    
    
  3. Aggiungere il codice per determinare se è possibile elaborare qualsiasi intestazione SOAP sconosciuta.

    Se la variabile membro è di tipo SoapUnknownHeader, un metodo di servizio Web XML può determinare il nome dell'intestazione SOAP, insieme ai dati passati dall'intestazione SOAP, tramite l'interrogazione della proprietà Element. La proprietà Name della proprietà Element identifica il nome dell'intestazione SOAP.

           foreach (SoapUnknownHeader header in unknownHeaders) 
           {
             // Check to see if this a known header.
             if (header.Element.Name == "MyKnownHeader")
    [Visual Basic]
           Dim header As SoapUnknownHeader       
           For Each header In unknownHeaders
             ' Check to see if this is a known header.
             If (header.Element.Name = "MyKnownHeader") Then
    
  4. Se si è in grado di elaborare un'intestazione SOAP specifica, impostare la proprietà DidUnderstand della variabile membro che rappresenta l'intestazione SOAP sconosciuta su true.

    Se un metodo di un servizio Web XML elabora un'intestazione SOAP sconosciuta e non imposta la proprietà DidUnderstand su true, è possibile che venga generata un'eccezione SoapHeaderException. Per ulteriori informazioni, vedere Gestione di intestazioni SOAP richieste da un client del servizio Web XML

             // Check to see if this is a known header.
             if (header.Element.Name == "MyKnownHeader")
                   header.DidUnderstand = true;
             else
                 // For those headers that cannot be 
                 // processed, set DidUnderstand to false.
                 header.DidUnderstand = false;
             }
    [Visual Basic]
             ' Check to see if this a known header.
             If (header.Element.Name = "MyKnownHeader") Then
                   header.DidUnderstand = True
             Else
                 ' For those headers that cannot be 
                 ' processed, set DidUnderstand to false.
                 header.DidUnderstand = False
             End If
    

    Nota   La proprietà DidUnderstand viene utilizzata dai servizi Web XML creati con ASP.NET per comunicare con il metodo di servizio Web XML e non fa parte della specifica SOAP. Il relativo valore non viene visualizzato in alcuna parte della richiesta o della risposta SOAP.

    Nota   Quando un client del servizio Web XML genera una classe proxy utilizzando lo Strumento del linguaggio di descrizione dei servizi Web (Wsdl.exe) e un servizio Web XML definisce la variabile membro che rappresenta un'intestazione SOAP tramite il tipo SoapUnknownHeader, alla classe proxy non viene aggiunto alcun riferimento a tale intestazione SOAP. Se un client del servizio Web XML decide di aggiungere questa intestazione SOAP alla richiesta SOAP, è necessario modificare la classe proxy aggiungendo una variabile membro e applicando un attributo SoapHeader al metodo eseguendo la chiamata al metodo di servizio Web XML appropriato.

Gestione di intestazioni SOAP richieste da un client del servizio Web XML

È possibile che un client richieda un metodo di servizio Web XML per interpretare la semantica dell'intestazione SOAP in modo corretto ed elaborarla di conseguenza affinché la richiesta SOAP abbia esito positivo. A tal fine, i client impostano l'attributo mustUnderstand dell'intestazione SOAP su 1. Con la richiesta SOAP che segue, ad esempio, si richiede al destinatario della richiesta SOAP di elaborare l'intestazione SOAP MyCustomSoapHeader.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" >
  <soap:Header>
    <MyCustomSoapHeader soap:mustUnderstand="1" xmlns="http://www.contoso.com">
      <custom>Keith</custom>
    </MyCustomSoapHeader>
  </soap:Header>
  <soap:Body>
    <MyUnknownHeaders xmlns="http://www.contoso.com" />
  </soap:Body>
</soap:Envelope>

La modalità utilizzata dal servizio Web XML per la gestione delle intestazioni richieste dal client varia in funzione della definizione dell'intestazione SOAP da parte del servizio Web XML, che può essere eseguita o meno. ASP.NET gestisce buona parte delle operazioni nel caso in cui il servizio Web XML definisca l'intestazione SOAP. Nella procedura seguente viene descritto come gestire entrambe le situazioni.

Per gestire intestazioni SOAP non definite dal servizio Web XML, ma richieste da un client del servizio Web XML

  • Eseguire i passaggi per la gestione di intestazioni SOAP sconosciute da un client del servizio Web XML, prestando particolare attenzione alla proprietà DidUnderstand dell'intestazione SOAP.

    Per intestazioni SOAP non definite dal servizio Web XML, il valore iniziale di DidUnderstand è false. Se ASP.NET rileva intestazioni SOAP con la relativa proprietà DidUnderstand impostata su false dopo la restituzione del metodo di servizio Web XML, viene automaticamente generata un'eccezione SoapHeaderException.

Per gestire intestazioni SOAP richieste da un client del servizio Web XML e definite dal servizio Web XML

  • Eseguire i passaggi per l'elaborazione di intestazioni SOAP all'interno di servizi Web XML creati con ASP.NET in ciascun metodo di servizio Web XML.

    Per intestazioni SOAP definite dal servizio Web XML ed elaborate nel metodo di servizio Web XML che riceve l'intestazione SOAP, in ASP.NET si presuppone che il servizio Web XML riconosca l'intestazione SOAP e imposti il valore iniziale di DidUnderstand su true.

Il servizio Web XML MyWebService riportato di seguito definisce l'intestazione SOAP MyHeader e ne richiede l'invio con qualsiasi chiamata al metodo di servizio Web XML MyWebMethod. Inoltre, MyWebMethod elabora qualsiasi intestazione SOAP sconosciuta. Per le intestazioni SOAP che MyWebMethod è in grado di elaborare, DidUnderstand è impostato su true.

<%@ WebService Language="C#" Class="MyWebService" %>
using System.Web.Services;
using System.Web.Services.Protocols;

// Define a SOAP header by deriving from the SoapHeader class.
public class MyHeader : SoapHeader {
    public string MyValue;
}
public class MyWebService {
    public MyHeader myHeader;

    // Receive all SOAP headers other than the MyHeader SOAP header.
    public SoapUnknownHeader[] unknownHeaders;
 
    [WebMethod]
    [SoapHeader("myHeader")]
    //Receive any SOAP headers other than MyHeader.
    [SoapHeader("unknownHeaders")]
    public string MyWebMethod() 
    {
       foreach (SoapUnknownHeader header in unknownHeaders) 
       {
         // Perform some processing on the header.
         if (header.Element.Name == "MyKnownHeader")
               header.DidUnderstand = true;
         else
                // For those headers that cannot be 
                // processed, set DidUnderstand to false.
                header.DidUnderstand = false;
       }
       return "Hello";
    }
}
[Visual Basic]
<%@ WebService Language="VB" Class="MyWebService" %>
Imports System.Web.Services
Imports System.Web.Services.Protocols

' Define a SOAP header by deriving from the SoapHeader class.
Public Class MyHeader : Inherits SoapHeader
    Public MyValue As String
End Class

Public Class MyWebService
    Public myHeader As MyHeader
    
    ' Receive all SOAP headers other than the MyHeader SOAP header.
    Public unknownHeaders() As SoapUnknownHeader    
    
    <WebMethod, _
     SoapHeader("myHeader"), _
     SoapHeader("unknownHeaders")> _
    Public Function MyWebMethod() As String
        'Receive any SOAP headers other than MyHeader.
        Dim header As SoapUnknownHeader        For Each header In unknownHeaders
            ' Perform some processing on the header.
            If header.Element.Name = "MyKnownHeader" Then
                header.DidUnderstand = True
            ' For those headers that cannot be 
            ' processed, set DidUnderstand to false.
            Else
                header.DidUnderstand = False
            End If
        Next header
        Return "Hello"
    End Function
End Class

Nota   La proprietà DidUnderstand viene utilizzata da ASP.NET per comunicare con il metodo di servizio Web XML. Non fa parte della specifica SOAP e il relativo valore non viene visualizzato in alcuna parte della richiesta o della risposta SOAP.

Se un servizio Web XML inoltra un'intestazione SOAP, è molto importante seguire le regole presenti nella specifica SOAP, specialmente quelle relative al valore di Actor. Per ulteriori informazioni, vedere il sito Web W3C all'indirizzo http://www.w3.org/TR/SOAP/ (informazioni in lingua inglese).

Gestione di errori che si verificano durante l'elaborazione di un'intestazione SOAP

Quando un servizio Web XML rileva un errore relativo all'elaborazione di un'intestazione, deve essere generata un'eccezione SoapHeaderException. L'utilizzo di questa classe di eccezione consente ai servizi Web XML di formattare la risposta correttamente. Se il client è stato creato con .NET Framework, riceverà una SoapHeaderException con il relativo contenuto, proprietà InnerException compresa, nella proprietà Message. La proprietà InnerException dell'eccezione SoapHeaderException intercettata dal client sarà null. Questo è un modello di programmazione supportato da .NET Framework, poiché l'eccezione viene inviata in rete in un elemento XML SOAP <Fault>, come stabilito dalla specifica SOAP. Per ulteriori informazioni sulle eccezioni, vedere Gestione e generazione di eccezioni nei servizi Web XML.

Nell'esempio di codice seguente viene generata un'eccezione SoapHeaderException se un client esegue una richiesta SOAP al metodo di servizio Web XML MyWebMethod impostando la proprietà Username su guest.

<%@ WebService Language="C#" Class="MyWebService" %>
using System.Web.Services;
using System.Web.Services.Protocols;

// Define a SOAP header by deriving from the SoapHeader class.
public class MyHeader : SoapHeader
{
  public DateTime Created;
  public DateTime Expires;
  public DateTime Received;
} 

[WebService(Namespace="http://www.contoso.com")]
public class MyWebService 
{
    // Add a member variable of the type deriving from SoapHeader.
    public MyHeader myHeaderMemberVariable;
 
    // Apply a SoapHeader attribute.
    [WebMethod]
    [SoapHeader("myHeaderMemberVariable")]
    public void MyWebMethod() 
    {
       if (timeStamp == null)
          timeStamp = new MyHeader();
       else
       {
          // Check whether the SOAP message is expired.
          if ((timeStamp.Expires.CompareTo(DateTime.UtcNow)) <= 0)
          {
             // The SOAP message is expired, so throw a SOAP header
             // exception indicating that.
             SoapHeaderException se = new SoapHeaderException(
               "SOAP message expired before reaching this node.",
               SoapException.ClientFaultCode, 
               this.Context.Request.Url.ToString());
             throw se;
          }
       }
    }
}
[Visual Basic]
<%@ WebService Language="VB" Class="MyWebService" %>
Imports System.Web.Services
Imports System.Web.Services.Protocols

' Define a SOAP header by deriving from the SoapHeader class.
Public Class MyHeader 
  Inherits SoapHeader
    Public Created As DateTime
    Public Expires As DateTime
    Public Received As DateTime
End Class

<WebService(Namespace:="http://www.contoso.com")> _
Public Class MyWebService
    ' Add a member variable of the type deriving from SoapHeader.
    Public myHeaderMemberVariable As MyHeader    
    
    ' Apply a SoapHeader attribute.
    <WebMethod, _
     SoapHeader("myHeaderMemberVariable")> _
    Public Sub MyWebMethod()
       If (TimeStamp Is Nothing) Then
          TimeStamp = New MyHeader
       Else
           ' Check whether the SOAP message is expired.
           If ((TimeStamp.Expires.CompareTo(DateTime.UtcNow)) <= 0) Then
             ' The SOAP message is expired, so throw a SOAP header
             ' exception indicating that.
             Dim se As New SoapHeaderException( _
                "SOAP message expired before reaching this node.", _
                SoapException.ClientFaultCode, _
                Me.Context.Request.Url.ToString())
             Throw se    
           End If
       End If
    End Sub
End Class

Nota: In .NET Framework versione 1.0 è inclusa la proprietà SoapHeaderAttribute.Required, che, se impostata su true, consente a un servizio Web XML di richiedere a un client l'invio di una specifica intestazione SOAP. ASP.NET indica l'esigenza di una intestazione SOAP in un documento WSDL generato impostando l'attributo wsdl:required su "true" nell'elemento soap:header. Se i client del servizio Web XML creato dal documento WSDL non inviano l'intestazione SOAP richiesta, riceveranno un errore SOAP o, se sono client .NET Framework, una SoapHeaderException. Ai fini dell'interoperabilità con altre implementazioni SOAP, questa funzionalità è stata rimossa nelle versioni successive.

Nella versione 1.1 la proprietà Required è obsoleta e l'attributo wsdl:required di un elemento soap:header presente in un documento WSDL viene ignorata dallo strumento del linguaggio di descrizione dei servizi Web (Wsdl.exe). Poiché non è più possibile richiedere un'intestazione SOAP, occorrerà che i servizi Web XML verifichino che il campo o la proprietà che rappresenta l'intestazione SOAP non sia null prima di accedervi.

Vedere anche

SoapHeader | SoapHeaderAttribute | SoapHeaderException | SoapUnknownHeader | Generazione di servizi Web XML mediante ASP.NET | Generazione di client dei servizi Web XML