[INP2003] [PRB] Microsoft Office InfoPath では ADO.NET の DataSet を返す Web サービスを使用できない

文書翻訳 文書翻訳
文書番号: 822020 - 対象製品
すべて展開する | すべて折りたたむ

目次

現象

ADO.NET の DataSet (System.Data.DataSet) を返す Web サービスから InfoPath のフォームが作成されると、次のエラー メッセージが InfoPath から返される場合があります。

XML データ ファイルに XML スキーマ情報が含まれていますが、これは許可されていません。

原因

InfoPath では、ADO.NET の DataSet を直接使用できません。InfoPath の処理の対象となるのは、Generic XML ペイロードです。Web サービスによって返される ADO.NET の DataSet は、特殊な XML 形式でシリアル化されるため、InfoPath では ADO.NET の DataSet を直接処理できません。
  • Web サービスのメソッドとプロパティを定義する WSDL (Web Service Definition Language) ファイルでは、DataSet 型はスキーマの開始タグ <xsd:any /> で表現されます。Web サービスによって返される XML ドキュメントのスキーマの推測を InfoPath で行うことはできますが、その場合は Web サービスに対してサンプル呼び出しを行う必要があります。
  • ADO.NET の DataSet には、格納されているデータを記述するインライン スキーマが含まれています。このバージョンの InfoPath では、インライン スキーマはサポートされていません。
  • ADO.NET の DataSet 内のデータは、インライン スキーマで記述されていない <diffgr:diffgram> XML 要素に挟まれています。ADO.NET の DataSet のデータを含む XML 要素にも、このスキーマで記述されていない追加の属性があります。データがスキーマと一致しないため、InfoPath フォームではデータの検証ができません。
  • InfoPath には、ADO.NET の DataSet のような変更履歴をサポートする機能は組み込まれていません。たとえば、ADO.NET の DataSet では、最後に変更内容が確定してから追加、変更、または削除されたフィールドと行の履歴が保存されます (XML ストリームの diffgram 要素と "diffgr" 名前空間は、このためのものです)。変更履歴をサポートするためには、InfoPath で、.NET Framework を公開して DataSet オブジェクトをホストし、XML データを管理するか、または、機能を再実装する必要があります。このバージョンの InfoPath では、これらのどちらの方法も使用できません。

解決方法

この問題を回避するには、元の Web サービスのメソッドから返される ADO.NET の DataSet を受け付ける Web サービスのメソッドを新規に作成し、インライン スキーマと diffgram 要素と属性を削除して、その削除済みの XML を InfoPath に返します。この回避策の 2 つの実装方法については、「詳細」を参照してください。

状況

この動作は仕様です。

詳細

問題の再現手順

  1. Microsoft Visual Studio .NET を起動し、Microsoft C# の ASP.NET Web サービス プロジェクトを新規作成します。このプロジェクトの名前を NorthwindDataSet に変更します。

    これを行うには、[場所] ボックスの値を //localhost/NorthwindDataSet に変更し、[OK] をクリックします。
  2. [プロジェクト] メニューの [Web サービスの追加] をクリックします。新しい Web サービスに CustomerInfo.asmx という名前を付けます。
  3. 新しい 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;
       }
    }
    
    このサンプル コードでは、Web サービスと Microsoft SQL Server の両方が実行されているローカル コンピュータに接続します。System.Data.SqlConnection オブジェクトで使用される接続文字列を変更して、SQL Server が実行されている別のコンピュータに接続することもできます。必要に応じて、Web サービスからデータベースにアクセスできるように、SQL Server の権限を構成してください。 関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
    815154 HOW TO: Configure SQL Server Security for .NET Applications
    815154 [HOWTO] .NET アプリケーション用に SQL Server のセキュリティを構成する方法
  4. [CustomerInfo.asmx.cs] ページの一番上の USING ステートメントに次のコードを追加します。
    using System.Data.SqlClient;
  5. NorthwindDataSet プロジェクトをコンパイルします。
  6. InfoPath を起動し、[ファイル] メニューの [フォームのデザイン] をクリックします。
  7. [フォームのデザイン] 作業ウィンドウで、[データ ソースから新規作成] をクリックします。
  8. データ ソース セットアップ ウィザードで、データ ソースの種類として [Web サービス] をクリックし、[次へ] をクリックします。
  9. [データの受信] を選択し、[次へ] をクリックします。
  10. CustomerInfo Web サービスの URL (http://localhost/NorthwindDataSet/CustomerInfo.asmx など) を入力し、[次へ] をクリックします。
  11. [処理を選択してください] ボックスの一覧の [GetCustomerInfo] をクリックし、[次へ] をクリックします。
  12. [パラメータ] ボックスの一覧の [s0:CustomerID] をクリックし、[サンプル値の設定] をクリックします。[値の設定] ダイアログ ボックスで、ALFKI と入力し、[OK] をクリックします。
  13. [次へ] をクリックします。

    : 「現象」に記載したエラー メッセージが、InfoPath で表示されます。
この問題を回避するには、次のような手順を使用して、ADO.NET の DataSet の XML から互換性のない要素を削除する、Web サービス メソッドを新しく追加します。これを行うことで、この XML データを InfoPath で使用できるようになります。ここに示した Web サービスは、インライン スキーマ情報を XML データから削除する Web サービス メソッドと、XML データを厳密に型指定されたラッパー クラスにシリアル化し、それを返す Web サービス メソッドです。

各メソッドには、それぞれ長所と短所があります。
  • 回避策 1

    インライン スキーマおよび互換のない XML 属性を削除する

    この回避方法は、実装が簡単であるという利点があります。また、何らかの理由で元の Web サービスが返す XML データが変更されても、この回避策をその新しいデータにあわせて変更する必要がありません。

    ただし、この回避策にも欠点があります。この回避策は、XML データのスキーマを記述するものではありません。そのため InfoPath では、サンプル データからスキーマを推測する必要があります。Web サービス メソッドから返される可能性のある要素と属性がすべてサンプル データに含まれていないと、InfoPath が推測するスキーマにはそれらの要素は含まれません。サンプル呼び出しにない要素や属性を返すクエリを実行すると、InfoPath によりエラーが表示されます。

    回避策 1 を実装するには、次の手順を実行します。
    1. Visual Studio .NET で NorthwindDataSet プロジェクトを開きます。
    2. [プロジェクト] メニューの [Web サービスの追加] をクリックします。新しい Web サービスに IPCustomerInfo.asmx という名前を付けます。
    3. 新しい 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;
      }
      
      このサンプル コードでは、元の Web サービスを使用して ADO.NET の DataSet を取得し、インライン スキーマ情報が含まれない XML ドキュメントを新規作成します。
    4. NorthwindDataSet プロジェクトをコンパイルします。
    5. InfoPath を起動し、[ファイル] メニューの [フォームのデザイン] をクリックします。
    6. [フォームのデザイン] 作業ウィンドウで、[データ ソースから新規作成] をクリックします。
    7. [データ ソース セットアップ ウィザード] ダイアログ ボックスで、データ ソースの種類として [Web サービス] をクリックし、[次へ] をクリックします。
    8. [データの受信] をクリックし、[次へ] をクリックします。
    9. IPCustomerInfo Web サービスの URL (http://localhost/NorthwindDataSet/IPCustomerInfo.asmx など) を入力し、[次へ] をクリックします。
    10. [処理を選択してください] ボックスの一覧の [GetCustomerInfoNoSchema] をクリックし、[次へ] をクリックします。
    11. [パラメータ] ボックスの一覧の [s0:CustomerID] をクリックし、[サンプル値の設定] をクリックします。[値の設定] ダイアログ ボックスで、ALFKI と入力し、[OK] をクリックします。
    12. [次へ] をクリックし、[完了] をクリックします。
    13. [データ ソース] 作業ウィンドウの [使用するデータ ソース] ボックスの一覧で、[queryFields] のツリーを展開し、[CustomerID] をクエリ ビューにドラッグします。
    14. [データ ソース] 作業ウィンドウの [使用するデータソース] ボックスの一覧で、[dataFields] のツリーを展開し、[Customers] をデータ入力ビューにドラッグします。表示されるメニューの [コントロール付きセクション] をクリックします。
    15. フォームをプレビューして、テストします。Web サービスから返される可能性のある要素がすべてサンプル データに含まれているわけではないため、[QUEEN] などの CustomerID を使用すると、クエリでエラーが発生します。
  • 回避策 2

    厳密に型指定されたラッパー クラスを作成してADO.NET の DataSet の XML データをシリアル化する

    この回避策は、前の回避策より実装が難しくなります。また、この回避策では、使用する各 Web サービス メソッドに合わせてカスタマイズする必要があり、その Web サービス メソッドで返すデータのスキーマを変更しないようにする必要があります。一方、この回避策では返す XML データのスキーマを記述するため、InfoPath ではデータの構造を推測する必要がありません。そのため、この回避策で作成される InfoPath のフォームでは、任意の要素と属性によるエラーが発生しにくくなります。
    1. Microsoft Internet Explorer で、CustomerInfo Web サービスのテスト ページの URL (http://localhost/NorthwindDataSet/CustomerInfo.asmx など) に移動します。
    2. [GetCustomerInfo] をクリックして、このメソッドのテスト ページに移動します。
    3. [CustomerID] テキスト ボックスに ALFKI と入力し、[起動] をクリックします。
    4. 表示される XML から <xs:schema> 要素とその子要素をコピーし、メモ帳の新しいテキスト文書に貼り付けます。
    5. 貼り付けたテキストの行頭にある負符号 (-) をすべて削除し、CustomerInfo.xsd という名前で保存します。
    6. Visual Studio .NET コマンド プロンプトを開き、CustomerInfo.xsd を保存したディレクトリに移動します。
    7. 次の行を使用して、このスキーマ ファイルからラッパー クラスを作成します。
      xsd.exe CustomerInfo.xsd /c /l:cs
    8. Visual Studio .NET で NorthwindDataSet プロジェクトを開きます。
    9. [プロジェクト] メニューの [既存項目の追加] をクリックします。
    10. Xsd.exe ツールで作成した CustomerInfo.cs ファイルが置かれているフォルダに移動し、ファイルをクリックし、[開く] をクリックします。
    11. CustomerInfo クラスと CustomerInfoCustomers クラスの外側に名前空間 CustomerInfoWrapper を追加します。
    12. IPCustomerInfo.asmx Web サービスに、次のコードを追加します。
      /************************************************************************
         * 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;
      }
      
      このサンプル コードでは、元の Web サービスを使用して ADO.NET の DataSet を取得し、インライン スキーマ情報が含まれない XML ドキュメントを新規作成します。
    13. NorthwindDataSet プロジェクトをコンパイルします。
    14. InfoPath を起動し、[ファイル] メニューの [フォームのデザイン] をクリックします。
    15. [フォームのデザイン] 作業ウィンドウで、[データ ソースから新規作成] をクリックします。
    16. [データ ソース セットアップ ウィザード] ダイアログ ボックスで、データ ソースの種類として [Web サービス] をクリックし、[次へ] をクリックします。
    17. [データの受信] をクリックし、[次へ] をクリックします。
    18. IPCustomerInfo Web サービスの URL (http://localhost/NorthwindDataSet/IPCustomerInfo.asmx など) を入力し、[次へ] をクリックします。
    19. [処理を選択してください] ボックスの一覧の [GetCustomerInfoWrapper] をクリックし、[次へ] をクリックします。

      Web サービス メソッドのサンプル値を指定するページは表示されません。
    20. [完了] をクリックします。
    21. [データ ソース] 作業ウィンドウの [使用するデータ ソース] ボックスの一覧で、[queryFields] のツリーを展開し、[CustomerID] をクエリ ビューに追加します。
    22. [データ ソース] 作業ウィンドウの [使用するデータ ソース] ボックスの一覧で、[dataFields] のツリーを展開し、[Customers] をデータ入力ビューに追加します。
    23. フォームをプレビューし、テストします。

      有効な CustomerID であればどのような値でも、このフォームは正常に動作します。

関連情報

この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 822020 (最終更新日 2003-09-15) を基に作成したものです。

この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。

プロパティ

文書番号: 822020 - 最終更新日: 2003年11月19日 - リビジョン: 1.1
この資料は以下の製品について記述したものです。
  • Microsoft Office InfoPath 2003
キーワード:?
kbprb KB822020
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"

フィードバック

 

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