PRB: Microsoft Office InfoPath가 ADO.NET DataSet을 반환하는 웹 서비스를 사용할 수 없다

기술 자료 번역 기술 자료 번역
기술 자료: 822020 - 이 문서가 적용되는 제품 보기.
모두 확대 | 모두 축소

이 페이지에서

현상

ADO.NET DataSet(System.Data.DataSet)을 반환하는 웹 서비스에서 InfoPath 양식을 만들면 InfoPath에서 다음과 같은 오류 메시지가 나타날 수 있습니다.

XML 데이터 파일에 지원되지 않는 XML 스키마 정보가 있습니다.

원인

InfoPath는 ADO.NET DataSet을 직접 사용할 수 없습니다. InfoPath는 일반 XML 페이로드에서 작동합니다. 웹 서비스에서 반환되는 ADO.NET DataSet은 InfoPath에서 직접 작동될 수 없는 특수 XML 형식으로 serialize되어 있습니다.
  • 웹 서비스의 메서드와 속성을 정의하는 웹 서비스 정의 언어 파일에서는 DataSet 유형이 열린 스키마 태그, <xsd:any />로 표현됩니다. InfoPath가 웹 서비스에서 반환되는 XML 문서의 스키마를 추정할 수 있습니다. 그러나, InfoPath가 웹 서비스에 대한 예제 호출을 만들어 이 작업을 수행해야 합니다.
  • 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에서는 이러한 옵션 중 어떤 것도 사용할 수 없습니다.

해결 방법

이 문제를 해결하려면 원래 웹 서비스 메서드에서 반환되는 ADO.NET DataSet을 받고, 인라인 스키마와 diffgram 요소와 특성을 제거한 다음 정리된 XML을 InfoPath로 반환하는 새로운 웹 서비스 메서드를 만드십시오. 이러한 해결 방법의 두 가지 가능한 구현에 대해서는 "추가 정보" 절을 참조하십시오.

현재 상태

이것은 의도적으로 설계된 동작입니다.

추가 정보

문제를 재현하는 방법

  1. Microsoft Visual Studio .NET에서 새 Microsoft C# ASP.NET 웹 서비스 프로젝트를 만듭니다. 이 프로젝트의 이름을 NorthwindDataSet으로 변경합니다.

    이렇게 하려면 위치를 http://localhost/NorthwindDataSet으로 변경하면 됩니다.
  2. 프로젝트 메뉴에서 웹 서비스 추가를 누릅니다. 새 웹 서비스에 CustomerInfo.asmx라는 이름을 지정합니다.
  3. 새로운 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;
       }
    }
    
    예제 코드가 이 웹 서비스와 같은 컴퓨터에서 Microsoft SQL Server를 실행 중인 컴퓨터에 연결하려고 합니다. 또는, System.Data.SqlConnection 개체에서 사용하는 연결 문자열을 변경하여 SQL Server를 실행 중인 다른 컴퓨터에 연결할 수 있습니다. 웹 서비스가 데이터베이스에 액세스할 수 있도록 SQL Server 사용 권한을 구성해야 할 수 있습니다. 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조하십시오.
    815154 HOWTO: .NET 응용 프로그램에 대해 SQL Server 보안 구성
  4. CustomerInfo.asmx.cs 페이지의 맨 위에서 USING 문에 다음 코드를 추가합니다.
    using System.Data.SqlClient;
  5. NorthwindDataSet 프로젝트를 컴파일합니다.
  6. InfoPath를 시작합니다. 파일 메뉴에서 양식 디자인을 누릅니다.
  7. 양식 디자인 작업창에서 데이터 원본에서 새로 만들기를 누릅니다.
  8. 데이터 원본 설치 마법사 대화 상자에서 데이터 원본의 형식으로 웹 서비스를 선택한 후 다음을 누릅니다.
  9. 데이터 받기를 선택한 후 다음을 누릅니다.
  10. CustomerInfo 웹 서비스의 URL(예: http://localhost/NorthwindDataSet/CustomerInfo.asmx)을 입력한 후 다음을 누릅니다.
  11. 작업에 대해 GetCustomerInfo 메서드를 선택한 후 다음을 누릅니다.
  12. s0:CustomerID 매개 변수를 선택한 후 예제 값 설정을 누릅니다. 값 설정 대화 상자에서 ALFKI를 입력한 후 확인을 누릅니다.
  13. 다음을 누릅니다.

    참고 InfoPath가 "현상" 절에 나와 있는 오류 메시지를 표시합니다.
문제를 해결하려면 다음과 유사한 단계를 수행하여 ADO.NET DataSet의 XML에서 호환되지 않는 요소를 제거하는 새로운 웹 서비스 메서드를 추가하면 됩니다. XML 데이터를 InfoPath에서 사용할 수 있도록 이 작업을 수행합니다. 웹 서비스 메서드가 XML 데이터에서 인라인 스키마 정보를 제거하거나, 강력하게 형식화된 래퍼 클래스에 XML 데이터를 serialize하고 이 데이터를 반환할 수 있습니다.

메서드마다 장점과 단점이 있습니다.
  • 해결 방법 1

    인라인 스키마와 호환되지 않는 XML 특성 제거

    이 해결 방법은 구현이 간단한 것이 장점입니다. 또한, 원래 웹 서비스가 반환한 XML 데이터가 어떤 이유로든 변경된 경우 이 해결 방법을 사용하면 새로운 데이터에서 작업하기 위해 변경할 필요가 없습니다.

    그러나, 이 해결 방법에는 단점도 있습니다. 이 해결 방법은 XML 데이터의 스키마를 설명하지 않습니다. 따라서, InfoPath가 예제 데이터로부터 스키마를 추정해야 합니다. 예제 데이터에 웹 서비스 메서드가 반환할 수 있는 가능한 모든 요소와 특성이 없으면 InfoPath가 추정하는 스키마에 이들 요소가 포함되지 않습니다. 예제 호출에 없는 요소나 특성을 반환하는 쿼리를 실행하면 InfoPath가 오류를 표시합니다.

    해결 방법 1을 구현하려면 다음과 같이 하십시오.
    1. Visual Studio .NET에서 NorthwindDataSet 프로젝트를 엽니다.
    2. 프로젝트 메뉴에서 웹 서비스 추가를 누릅니다. 새 웹 서비스에 IPCustomerInfo.asmx라는 이름을 지정합니다.
    3. 새 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;
      }
      
      예제 코드가 원래 웹 서비스를 사용하여 ADO.NET DataSet을 제공한 다음 인라인 스키마 정보 없이 새로운 XML 문서를 만듭니다.
    4. NorthwindDataSet 프로젝트를 컴파일합니다.
    5. InfoPath를 시작합니다. 파일 메뉴에서 양식 디자인을 누릅니다.
    6. 양식 디자인 작업창에서 데이터 원본에서 새로 만들기를 누릅니다.
    7. 데이터 원본 설치 마법사 대화 상자에서 데이터 원본의 형식으로 웹 서비스를 선택한 후 다음을 누릅니다.
    8. 데이터 받기를 선택한 후 다음을 누릅니다.
    9. IPCustomerInfo 웹 서비스의 URL(예: http://localhost/NorthwindDataSet/IPCustomerInfo.asmx)을 입력한 후 다음을 누릅니다.
    10. 작업에 대해 GetCustomerInfoNoSchema 메서드를 선택한 후 다음을 누릅니다.
    11. s0:CustomerID 매개 변수를 선택한 후 예제 값 설정을 누릅니다. 값 설정 대화 상자에서 ALFKI를 입력한 후 확인을 누릅니다.
    12. 다음을 누른 후 마침을 누릅니다.
    13. 데이터 원본 작업창의 queryFields 그룹에서 CustomerID 필드를 이동하여 쿼리 보기에 추가합니다.
    14. 데이터 원본 작업창의 dataFields 그룹에서 Customers 그룹을 이동하여 데이터 입력 보기에 추가합니다. 구역(컨트롤 포함)을 누릅니다.
    15. 양식을 미리 본 후 테스트합니다. QUEEN과 같은 일부 고객 ID의 경우에 예제 데이터에 웹 서비스가 반환할 수 있는 가능한 모든 요소가 포함되어 있지 않아 쿼리에 오류가 발생합니다.
  • 해결 방법 2

    강력하게 형식화된 래퍼 클래스를 만들어 ADO.NET DataSet의 XML 데이터 Serialize

    이 해결 방법은 이전 해결 방법보다 구현하는 것이 어렵습니다. 또한, 이 해결 방법은 이를 사용할 각 웹 서비스 메서드에 맞추어야 하고 웹 서비스 메서드가 반환하는 데이터의 스키마를 변경하지 않아야 합니다. 그러나, 이 해결 방법은 반환하는 XML 데이터의 스키마를 설명합니다. 따라서, InfoPath가 데이터의 구조를 추정하지 않아도 됩니다. 그러므로, 이 해결 방법을 통해 만들어지는 InfoPath 양식은 옵션 요소와 특성으로 인한 오류가 발생할 가능성이 적습니다.
    1. Microsoft Internet Explorer에서 CustomerInfo 웹 서비스 테스트 페이지의 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 웹 서비스에 다음 코드를 추가합니다.
      /************************************************************************
         * 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;
      }
      
      예제 코드가 원래 웹 서비스를 사용하여 ADO.NET DataSet을 제공한 다음 인라인 스키마 정보 없이 새로운 XML 문서를 만듭니다.
    13. NorthwindDataSet 프로젝트를 컴파일합니다.
    14. InfoPath를 시작합니다. 파일 메뉴에서 양식 디자인을 누릅니다.
    15. 양식 디자인 작업창에서 데이터 원본에서 새로 만들기를 누릅니다.
    16. 데이터 원본 설치 마법사 대화 상자에서 데이터 원본의 형식으로 웹 서비스를 선택한 후 다음을 누릅니다.
    17. 데이터 받기를 선택한 후 다음을 누릅니다.
    18. IPCustomerInfo 웹 서비스의 URL(예: http://localhost/NorthwindDataSet/IPCustomerInfo.asmx)을 입력한 후 다음을 누릅니다.
    19. 작업에 대해 GetCustomerInfoWrapper 메서드를 선택한 후 다음을 누릅니다.

      InfoPath가 웹 서비스 메서드에 대해 예제 값을 지정하라는 내용의 메시지를 나타내지 않습니다.
    20. 마침을 누릅니다.
    21. 데이터 원본 작업창의 queryFields 그룹에서 CustomerID 필드를 이동하여 쿼리 보기에 추가합니다.
    22. 데이터 원본 작업창의 dataFields 그룹에서 Customers 그룹을 이동하여 데이터 입력 보기에 추가합니다.
    23. 양식을 미리 본 후 테스트합니다.

      이 양식에는 올바른 고객 ID가 나타나는지 확인합니다.




Microsoft 제품 관련 기술 전문가들과 온라인으로 정보를 교환하시려면 Microsoft 뉴스 그룹에 참여하시기 바랍니다.

속성

기술 자료: 822020 - 마지막 검토: 2003년 12월 8일 월요일 - 수정: 1.3
본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft Office InfoPath 2003
키워드:?
kbprb KB822020

피드백 보내기

 

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