PRB: Impossibile utilizzare un servizio Web che restituisce un dataset ADO.NET in Microsoft Office InfoPath

Traduzione articoli Traduzione articoli
Identificativo articolo: 822020 - Visualizza i prodotti a cui si riferisce l?articolo.
Espandi tutto | Chiudi tutto

In questa pagina

Sintomi

Se viene creato un modulo di InfoPath da un servizio Web che restituisce un dataset ADO.NET (System.Data.DataSet), č possibile che in InfoPath venga visualizzato il seguente messaggio di errore:

Il file di dati XML include informazioni dello schema XML, condizione non consentita.

Cause

In InfoPath non č consentito utilizzare direttamente dataset ADO.NET, in quanto vengono utilizzati payload XML generici. I dataset ADO.NET restituiti dai servizi Web sono serializzati in un formato XML speciale che impedisce l'interazione diretta dei dataset ADO.NET con InfoPath.
  • Nel file WSDL (Web Service Definition Language) utilizzato per la definizione dei metodi e delle proprietā di un servizio Web il tipo DataSet č rappresentato da un tag di schema aperto, <xsd:any />. InfoPath č in grado di dedurre lo schema di un documento XML restituito da un servizio Web. Per ottenere queste informazioni, č tuttavia necessario che da InfoPath venga effettuata una chiamata di esempio al servizio Web.
  • Nel dataset ADO.NET č presente uno schema inline per la descrizione dei dati in esso memorizzati. Questa versione di InfoPath non supporta schemi inline.
  • I dati in un dataset ADO.NET sono contenuti in un elemento XML <diffgr:diffgram> che non viene descritto nello schema inline. Agli elementi XML contenenti i dati del dataset ADO.NET sono associati ulteriori attributi che non sono descritti nello schema. Poiché i dati non corrispondono allo schema, non possono essere convalidati nel modulo di InfoPath.
  • In InfoPath non č disponibile il supporto incorporato per il rilevamento delle modifiche come in un dataset ADO.NET. Ad esempio, in un dataset ADO.NET vengono registrati i campi e le righe aggiunti, modificati o eliminati dall'ultima accettazione. Questo č infatti lo scopo dell'elemento diffgram e dello spazio dei nomi "diffgr" nel flusso XML. Per supportare il rilevamento delle modifiche in InfoPath dovrebbe essere utilizzato .NET Framework ed essere presente un oggetto DataSet per gestire i dati XML o per reimplementare la funzionalitā. Nessuna di queste opzioni č disponibile in questa versione di InfoPath.

Risoluzione

Per risolvere il problema, creare un nuovo metodo per il servizio Web che consenta di accettare il dataset ADO.NET restituito dal metodo del servizio Web originale, di rimuovere lo schema inline, gli attributi e gli elementi diffgram e di restituire infine i dati XML puliti a InfoPath. Per due possibili implementazioni di questa soluzione, fare riferimento alla sezione "Informazioni".

Status

Si tratta di un comportamento legato alla progettazione del prodotto.

Informazioni

Procedura per riprodurre il problema

  1. In Microsoft Visual Studio .NET creare un nuovo progetto di servizio Web ASP.NET di Microsoft C#. Modificare il nome del progetto in NorthwindDataSet.

    Per effettuare questa operazione č possibile modificare il percorso in http://localhost/NorthwindDataSet.
  2. Scegliere Aggiungi servizio Web dal menu Progetto. Denominare il nuovo servizio Web CustomerInfo.asmx.
  3. Aggiungere il codice seguente al nuovo servizio Web CustomerInfo.asmx:
    /************************************************************************
       * GetCustomerInfo -- This method retrieves information from the 
       * Customer table of the Northwind database and then returns it in an
       * ADO.NET DataSet.
       * Parameters: CustomerID is the string that contains the CustomerID of the 
       *                           customer to retrieve the information for.
       * Returns: An ADO.NET DataSet that contains information about the customer.
       * *********************************************************************/
    [WebMethod]
    public System.Data.DataSet GetCustomerInfo( string CustomerID )
    {
       try
       {
          //Create a Microsoft SQL Server connection to the local SQL Server.
          System.Data.SqlClient.SqlConnection theConnection = new SqlConnection();
          theConnection.ConnectionString = "Data Source=(local);" + 
             "Integrated Security=SSPI;Initial Catalog=northwind";
          
          //Create an SQL Command to query the data.
          System.Data.SqlClient.SqlCommand theCommand = new SqlCommand();
          theCommand.Connection = theConnection;
          theCommand.CommandText = "SELECT \"CustomerID\",\"CompanyName\"," + 
             "\"ContactName\",\"ContactTitle\",\"Address\",\"City\",\"Region\"," + 
             "\"PostalCode\",\"Country\",\"Phone\",\"Fax\" FROM \"Customers\" " + 
             "WHERE CustomerID='" + CustomerID + "'";
       
          //Create an SQL DataAdapter to read the data.
          System.Data.SqlClient.SqlDataAdapter theDataAdapter = new SqlDataAdapter();
          theDataAdapter.SelectCommand = theCommand;
    
          //Open the command, and then read the data.
          theConnection.Open();
          System.Data.DataSet theCustomerInfo = new DataSet();
          theCustomerInfo.DataSetName = "CustomerInfo";
          theCustomerInfo.Namespace = "http://localhost/NorthwindDataSet/CustomerInfo";
          theDataAdapter.Fill( theCustomerInfo, "Customers" );
    
          //Clean up.
          theConnection.Close();
       
          //Return the result.
          return theCustomerInfo;
       }
       catch(Exception ex)
       {
          return null;
       }
    }
    
    Tramite il codice di esempio viene effettuato il tentativo di stabilire la connessione a un computer che esegue Microsoft SQL Server e nel quale viene eseguito il servizio Web. In alternativa, č possibile modificare la stringa di connessione utilizzata dall'oggetto System.Data.SqlConnection per stabilire la connessione con un altro computer che esegue SQL Server. Per consentire l'accesso al database da parte del servizio Web, potrebbe essere necessario configurare le autorizzazioni di SQL Server. Per ulteriori informazioni, fare clic sul numero dell'articolo della Microsoft Knowledge Base riportato di seguito (il contenuto potrebbe essere in inglese):
    815154 HOW TO: Configurare la protezione in SQL Server per le applicazioni .NET
  4. All'inizio della pagina CustomerInfo.asmx.cs aggiungere il codice riportato di seguito alle istruzioni USING:
    using System.Data.SqlClient;
  5. Compilare il progetto NorthwindDataSet.
  6. Avviare InfoPath. Scegliere Progetta modulo dal menu File.
  7. Nel riquadro attivitā relativo alla progettazione di un modulo fare clic su Nuovo da origine dati.
  8. Nella finestra di dialogo Configurazione guidata origine dati selezionare il tipo di origine dati Servizio Web, quindi scegliere Avanti.
  9. Fare clic su Ricezione dati e scegliere Avanti.
  10. Digitare l'URL del servizio Web CustomerInfo, ad esempio http://localhost/NorthwindDataSet/CustomerInfo.asmx, quindi scegliere Avanti.
  11. Selezionare il metodo GetCustomerInfo per l'operazione, quindi scegliere Avanti.
  12. Selezionare il parametro s0:CustomerID, quindi fare clic su Imposta valore di esempio. Nella finestra di dialogo Imposta valore digitare ALFKI, quindi scegliere OK.
  13. Scegliere Avanti.

    Nota Verrā visualizzato il messaggio di errore riportato nella sezione "Sintomi".
Per risolvere il problema, č possibile seguire procedure analoghe a quelle riportate di seguito per aggiungere al servizio Web un nuovo metodo che consenta di rimuovere gli elementi non compatibili dai dati XML del dataset ADO.NET. Questa operazione viene effettuata per utilizzare i dati XML in InfoPath. Il metodo del servizio Web consente di rimuovere le informazioni sullo schema inline dai dati XML oppure di serializzare i dati XML in una classe wrapper tipizzata in modo sicuro, restituendoli in questo formato.

Ogni metodo presenta vantaggi e svantaggi.
  • Soluzione 1

    Rimuovere lo schema inline e gli attributi XML non compatibili

    Questa soluzione č facile da implementare e inoltre, se i dati XML restituiti dal servizio Web originale vengono modificati per qualsiasi ragione, non sarā necessario apportare modifiche per l'utilizzo dei nuovi dati.

    Questa soluzione presenta comunque anche uno svantaggio, poiché non consente di ottenere una descrizione dello schema dei dati XML. Lo schema dovrā pertanto essere dedotto in InfoPath dai dati di esempio. Se questi non contengono tutti i possibili elementi e attributi che possono essere restituiti dal servizio Web, tali elementi non saranno contenuti nello schema dedotto da InfoPath. Se viene eseguita una query che restituisce elementi o attributi non contenuti nella chiamata di esempio, in InfoPath verrā visualizzato un errore.

    Per implementare la Soluzione 1, attenersi alla seguente procedura:
    1. In Visual Studio .NET aprire il progetto NorthwindDataSet.
    2. Scegliere Aggiungi servizio Web dal menu Progetto. Denominare il nuovo servizio Web IPCustomerInfo.asmx.
    3. Aggiungere il codice seguente al nuovo servizio Web IPCustomerInfo.asmx:
      /************************************************************************
         * GetCustomerInfoNoSchema: This method calls the GetCustomerInfo
         * method of the CustomerInfo.asmx Web service, and then strips the 
         * inline schema from the resulting DataSet.
         * Parameters: CustomerID is the string that contains the CustomerID of the 
         *                           customer to retrieve information for.
         * Returns: An XML Document with no inline schema.
         * *********************************************************************/
      [WebMethod]
      public System.Xml.XmlDocument GetCustomerInfoNoSchema( string CustomerID )
      {
         //Get the core data.
         CustomerInfo theCustomerInfoService = new CustomerInfo();
         System.Data.DataSet theDataSet = 
            theCustomerInfoService.GetCustomerInfo( CustomerID );
      
         //Create a new XmlDocument from the data of the dataset.
         System.Xml.XmlDocument theDocument = new System.Xml.XmlDocument();
         theDocument.LoadXml( theDataSet.GetXml() );
      
         //Return the result.
         return theDocument;
      }
      
      Nel codice di esempio viene utilizzato il servizio Web originale per fornire un dataset ADO.NET, quindi viene creato un nuovo documento XML senza informazioni sullo schema inline.
    4. Compilare il progetto NorthwindDataSet.
    5. Avviare InfoPath. Scegliere Progetta modulo dal menu File.
    6. Nel riquadro attivitā relativo alla progettazione di un modulo fare clic su Nuovo da origine dati.
    7. Nella finestra di dialogo Configurazione guidata origine dati selezionare il tipo di origine dati Servizio Web, quindi scegliere Avanti.
    8. Fare clic su Ricezione dati e scegliere Avanti.
    9. Digitare l'URL del servizio Web IPCustomerInfo, ad esempio http://localhost/NorthwindDataSet/IPCustomerInfo.asmx, quindi scegliere Avanti.
    10. Selezionare il metodo GetCustomerInfoNoSchema per l'operazione, quindi scegliere Avanti.
    11. Selezionare il parametro s0:CustomerID, quindi fare clic su Imposta valore di esempio. Nella finestra di dialogo Imposta valore digitare ALFKI, quindi scegliere OK.
    12. Scegliere Avanti, quindi Fine.
    13. Spostare il campo CustomerID dal gruppo queryFields nel riquadro attivitā relativo all'origine dati, quindi aggiungere il campo CustomerID alla visualizzazione Query.
    14. Spostare il gruppo Customers dal gruppo dataFields nel riquadro attivitā relativo all'origine dati, quindi aggiungere il gruppo Customers alla visualizzazione Immissione dati. Fare clic su Sezione con controlli.
    15. Visualizzare il modulo in anteprima e verificarne il funzionamento. Per alcuni ID cliente, come QUEEN, la query restituisce errori poiché nei dati di esempio non sono contenuti tutti gli elementi che possono essere restituiti dal servizio Web.
  • Soluzione 2

    Creare una classe wrapper tipizzata in modo sicuro per serializzare i dati XML del dataset ADO.NET

    L'implementazione di questa soluzione č pių difficile rispetto alla precedente e, inoltre, deve essere personalizzata in base a ogni metodo di servizio Web con cui viene utilizzata e lo schema dei dati restituiti non dovrā essere modificato dal metodo. Questa soluzione consente tuttavia di ottenere la descrizione dello schema dei dati XML restituiti. In InfoPath non sarā pertanto necessario dedurre la struttura dei dati. I moduli di InfoPath creati in base a questa soluzione non sono pertanto soggetti agli errori causati da elementi e attributi facoltativi.
    1. In Microsoft Internet Explorer passare all'URL della pagina di prova del servizio Web CustomerInfo, ad esempio http://localhost/NorthwindDataSet/CustomerInfo.asmx.
    2. Fare clic su GetCustomerInfo per passare alla pagina di prova relativa a questo metodo.
    3. Nella casella di testo CustomerID digitare ALFKI, quindi scegliere Invoke.
    4. Dai dati XML risultanti copiare l'elemento <xs:schema> e tutti gli elementi figlio, quindi incollarli in un nuovo documento di testo nel Blocco note.
    5. Rimuovere i caratteri - dal testo incollato e salvare il documento con nome CustomerInfo.xsd.
    6. Aprire il prompt dei comandi di Visual Studio .NET e passare alla directory in cui č stato salvato il file CustomerInfo.xsd.
    7. Utilizzare la riga seguente per creare una classe wrapper dal file dello schema:
      xsd.exe CustomerInfo.xsd /c /l:cs
    8. In Visual Studio .NET aprire il progetto NorthwindDataSet.
    9. Scegliere Aggiungi elemento esistente dal menu Progetto.
    10. Passare al file CustomerInfo.cs creato con lo strumento Xsd.exe e scegliere Apri.
    11. Aggiungere lo spazio dei nomi CustomerInfoWrapper alle classi CustomerInfo e CustomerInfoCustomers.
    12. Aggiungere il codice seguente al servizio Web IPCustomerInfo.asmx:
      /************************************************************************
         * GetCustomerInfoWrapper: This method calls the GetCustomerInfo
         * method of the CustomerInfo.asmx Web service, and then strips the 
         * inline schema from the resulting DataSet.
         * Parameters: CustomerID is the string that contains the CustomerID of the 
         *                           customer to retrieve information for.
         *                        exampleData is the wrapper class to fill with the data from the
         *                           ADO.NET DataSet.
         * Returns: none
         * *********************************************************************/
      [WebMethod]
      public void GetCustomerInfoWrapper( string CustomerID, 
         out CustomerInfoWrapper.CustomerInfo exampleData )
      {
         //Get the core data.
         CustomerInfo theCustomerInfoService = new CustomerInfo();
         System.Data.DataSet theDataSet = 
            theCustomerInfoService.GetCustomerInfo( CustomerID );
         theDataSet.Namespace = "http://localhost/NorthwindDataSet/CustomerInfo";
      
         //Create an in-memory stream to write the DataSet to.
         System.IO.MemoryStream theStream = new System.IO.MemoryStream();
      
         //Write the DataSet to the stream.
         theDataSet.WriteXml( theStream, XmlWriteMode.IgnoreSchema );
      
         //Move the streams seek pointer back to the beginning, or 
         //deserialization will fail.
         theStream.Seek(0, System.IO.SeekOrigin.Begin );
      
         //Create an XML Serializer to read the DataSet.
         System.Xml.Serialization.XmlSerializer ser = new
            System.Xml.Serialization.XmlSerializer(
               typeof(CustomerInfoWrapper.CustomerInfo));
      
         //Deserialize a CustomerInfo wrapper from the stream.
         exampleData = ((CustomerInfoWrapper.CustomerInfo)
            (ser.Deserialize( theStream )));
         return;
      }
      
      Nel codice di esempio viene utilizzato il servizio Web originale per fornire un dataset ADO.NET, quindi viene creato un nuovo documento XML senza informazioni sullo schema inline.
    13. Compilare il progetto NorthwindDataSet.
    14. Avviare InfoPath. Scegliere Progetta modulo dal menu File.
    15. Nel riquadro attivitā relativo alla progettazione di un modulo fare clic su Nuovo da origine dati.
    16. Nella finestra di dialogo Configurazione guidata origine dati selezionare il tipo di origine dati Web Service, quindi scegliere Avanti.
    17. Fare clic su Ricezione dati e scegliere Avanti.
    18. Digitare l'URL del servizio Web IPCustomerInfo, ad esempio http://localhost/NorthwindDataSet/IPCustomerInfo.asmx, quindi scegliere Avanti.
    19. Per l'operazione selezionare il metodo GetCustomerInfoWrapper, quindi scegliere Avanti.

      In InfoPath non verrā chiesto di specificare valori di esempio dal metodo del servizio Web.
    20. Scegliere Fine.
    21. Spostare il campo CustomerID dal gruppo queryFields nel riquadro attivitā relativo all'origine dati, quindi aggiungere il campo CustomerID alla visualizzazione Query.
    22. Spostare il gruppo Customers dal gruppo dataFields nel riquadro attivitā relativo all'origine dati, quindi aggiungere il gruppo Customers alla visualizzazione Immissione dati.
    23. Visualizzare il modulo in anteprima e verificarne il funzionamento.

      In questo modulo tutti gli ID cliente validi funzioneranno correttamente.

Proprietā

Identificativo articolo: 822020 - Ultima modifica: venerdė 28 novembre 2003 - Revisione: 1.1
Le informazioni in questo articolo si applicano a
  • Microsoft Office InfoPath 2003
Chiavi: 
kbprb KB822020
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.

Invia suggerimenti

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com