您無法在 InfoPath 2003 中自動送出結構化 XML 資料給 Web 服務

Office 2003 支援已結束

Microsoft 於 2014 年 4 月 8 日結束對 Office 2003 的支援。此變更已影響您的軟體更新和安全性選項。 瞭解這對您的意義為何且如何持續受保護。

本文已封存。本文係以「現狀」提供且不會再更新。
徵狀
當您使用內建的 InfoPath 送出功能從 InfoPath 表單將資料送出至 Web 服務時,可能會遭遇下列其中一個徵狀:
  • 您可能會收到錯誤訊息。根據要送出之資訊以及在該 Web 服務叫用的編碼方法而定,您收到的錯誤訊息會有所不同。
  • 您可能會發現,未預期的資料被送出給 Web 服務。
本文也討論下列主題:
  • InfoPath 如何送出資料給 Web 服務。
  • 兩種送出 InfoPath 表單內容給 Web 服務的方法。
發生的原因
當 InfoPath 送出資料給 Web 服務時,會送出選做為參數之 XML 節點的內容,但不會送出 XML 節點本身。這種方法通常運作順利。例如,您的 Web 服務方法可能如下:
[WebMethod]   public void SendSampleString( string sampleString )   {      //Do something interesting with the sample string.   } 
如果您送出下列 XML 項目給這個 Web 服務方法,則 sampleString 參數會填入 Hello, World!(如您所預期)。
<sampleElement>"Hello, World!"</sampleElement>
遺憾的是,這個行為可能導致難以將 XML 節點或整個 InfoPath 表單送出給 Web 服務。例如,您的 Web 服務方法可能如下:
[WebMethod]   public string SendXMLElement( System.Xml.XmlElement theElement )   {      //Report how many children the submitted node had.      return "Node with " + theElement.ChildNodes.Count + " children submitted.";   }
如果您使用內建的 InfoPath 送出功能將範例 XML 項目送出給此方法,則 theElement 參數的內容會產生錯誤。這個錯誤發生的原因,是因為只有 XML 項目的內容 (Hello, World!) 會傳送給 Web 服務方法。因為該字串不是有效的 XML 項目,所以 .NET Framework 會產生錯誤;錯誤訊息會顯示在 InfoPath 中。

當您嘗試送出整個 InfoPath 表單給範例 Web 服務方法時,也會發生類似的問題。在這種情況下,InfoPath 會送出 InfoPath 表單的所有子節點,但不會送出根節點。這樣會導致送出多個頂層 XML 節點。因為這也不是有效的 XML,所以 .NET Framework 會選取第一個頂層 XML 節點,並使用它做為 theElement 參數。所有其他節點則會被略過,看起來就像是這些節點都未送出。
解決方案
這個問題已經在 Microsoft Office 2003 Service Pack 1 中獲得修正。如果要解決這個問題,請取得 Microsoft Office 2003 的最新版 Service Pack。

如需詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件:
870924如何取得 Office 2003 的最新 Service Pack
其他可行方案
如果需要替代的解決方案,請在指令碼中寫入自訂的送出動作。您可以使用下列其中一種方法:
  • 使用次要資料來源來執行送出作業。
  • 撰寫程式碼,該程式碼可建立自訂的 SOAP 訊息,並將該訊息傳送給 Web 服務。

使用次要資料來源

  1. [工具] 功能表上,按一下 [次要資料來源]
  2. [次要資料來源] 對話方塊中,按一下 [新增]
  3. [資料來源安裝精靈] 的第一個頁面中,按一下 [Web 服務],然後按一下 [下一步]
  4. 輸入您要送出之 Web 服務的位置,然後按一下 [下一步]
  5. 選取您要使用的 Web 服務方法,然後按一下 [下一步]
  6. 當 InfoPath 提示您選取表單欄位或群組,以用於填入 Web 服務方法的參數時,請將參數保留空白,然後按一下 [下一步]
  7. 按一下以清除 [開啟表單時,連線到這個次要資料來源] 核取方塊,按一下 [完成],然後按一下 [確定],以關閉 [次要資料來源] 對話方塊。
  8. [工具] 功能表上,按一下 [送出表單]
  9. [送出表單] 對話方塊中,按一下 [啟用送出]
  10. [送出] 清單中,按一下 [使用自訂指令碼送出],然後按一下 [確定],以開啟 Microsoft Script Editor。
  11. XDocument::OnSubmitRequest 方法中,使用類似下列指令碼來送出整個表單。

    注意 您也可以送出該表單中的個別項目。
    try{      //Get a reference to the SendXMLElement secondary data source.      var objSendXMLElement = XDocument.GetDOM("SendXMLElement");      objSendXMLElement.setProperty( "SelectionNamespaces",         'xmlns:s1="http://joelallxp.microsoft.com/schema" ' +         'xmlns:s0="http://tempuri.org/" ' +         'xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution"' );       //Remove any data from the SendXMLElement secondary data source.      var objData = objSendXMLElement.selectSingleNode(         "/dfs:myFields/dfs:queryFields/s0:SendXMLElement/s0:theElement");      var objCurrentData = objData.selectNodes("@* | node()");      objCurrentData.removeAll();       //Clone the XDocument.      var objClonedDocument = XDocument.DOM.documentElement.cloneNode(true );      objData.appendChild( objClonedDocument );         //Call the "Query" method of the secondary data source to send the data.      XDocument.DataObjects("SendXMLElement").Query();         //Report the results of the submit.      XDocument.UI.Alert(          objSendXMLElement.selectSingleNode(            "/dfs:myFields/dfs:dataFields/s0:SendXMLElementResponse/s0:SendXMLElementResult").text );      eventObj.ReturnStatus = true;   }   catch(ex)   {      eventObj.ReturnStatus = false;   }

撰寫程式碼

  1. [工具] 功能表上,按一下 [送出表單]
  2. [送出表單] 對話方塊中,按一下 [啟用送出]
  3. [送出] 清單中,按一下 [使用自訂指令碼送出],然後按一下 [確定],以開啟 Microsoft Script Editor。
  4. XDocument::OnSubmitRequest 方法中,使用類似下列指令碼來送出整個表單。

    注意 您也可以送出該表單中的個別項目。
    try   {       //Create a SOAP object.      var objSOAPConnector = new ActiveXObject("MSOSOAP.HttpConnector30");         //Set the EndPointURL property to point to the Web service.      objSOAPConnector.Property("EndPointURL") = "http://server/WebService1/Submit.asmx";       //Set the SoapAction property to point to the Web service method. You can find this URI       //in the WSDL file of the Web service.      objSOAPConnector.Property("SoapAction") = "http://tempuri.org/SendXMLElement";      objSOAPConnector.Connect();            //Begin construction of a SOAP message to send to the Web service.      objSOAPConnector.BeginMessage();       var objSOAPSerializer = new ActiveXObject("MSOSoap.SoapSerializer30");      objSOAPSerializer.Init( objSOAPConnector.InputStream );      objSOAPSerializer.startEnvelope();      objSOAPSerializer.startBody();       //Construct the structure that marks the method name and the parameter name       //that you are sending.      objSOAPSerializer.StartElement( "SendXMLElement", "http://tempuri.org/" );      objSOAPSerializer.StartElement( "theNode", "http://tempuri.org/" );       //Write out the XML of the document.      objSOAPSerializer.WriteXml( XDocument.DOM.documentElement.xml );       //Finish each element.      objSOAPSerializer.EndElement();      objSOAPSerializer.EndElement();       //Call EndMessage to complete the SOAP message and send it to the Web service method.      //This results in the Web service method being called.      objSOAPSerializer.endBody();      objSOAPSerializer.endEnvelope();       objSOAPConnector.EndMessage();       //Use a SoapReader to read the response from the Web service method .      var ResponseReader = new ActiveXObject("MSOSOAP.SoapReader30");      ResponseReader.Load( objSOAPConnector.OutputStream );       //If there was no error, return true.      if (ResponseReader.Fault != null)      {         eventObj.ReturnStatus = false;         throw "Error submitting data: " + ResponseReader.Fault.xml;      }      eventObj.ReturnStatus = true;   }    catch (ex)   {       XDocument.UI.Alert("Failed to submit document: " + ex.description);    }
狀況說明
這是原本設計的作法。

這是 Microsoft Office InfoPath 2003 中原本設計的作法,而在 Microsoft Office InfoPath 2003 Service Pack 1 中已有所變更。
其他相關資訊

重現問題的步驟

  1. 建立包含下列兩個方法的 Web 服務:
    • 方法 1
      [WebMethod]   public void SendSampleString( string sampleString )   {      //Do something interesting with the sample string.   } 
    • 方法 2
      [WebMethod]   public string SendXMLElement( System.Xml.XmlElement theElement )   {      //Report how many children the submitted node had.      return "Node with " + theElement.ChildNodes.Count + " children submitted.";   }
  2. 選取 [新資料來源],以設計新的 InfoPath 表單。
  3. [資料來源安裝精靈] 中,選取 [Web 服務],然後按一下 [下一步]
  4. 按一下 [接收和送出資料],然後按一下 [下一步]
  5. 針對接收資料 Web 服務方法,請依照下列步驟執行:
    1. 輸入您先前建立之 Web 服務的 URL,然後按一下 [下一步]
    2. [選取作業] 清單中,按一下 [SendXMLElement],然後按一下 [下一步]
  6. 針對送出資料 Web 服務方法,請依照下列步驟執行:
    1. 輸入您先前建立之 Web 服務的 URL,然後按一下 [下一步]
    2. [選取作業] 清單中,按一下 [SendXMLElement],然後按一下 [下一步]
  7. 按一下 [修改] 按鈕,以選擇送出作業的參數。
  8. [dataFields] 清單中,按一下 [SendXMLElementResult],按一下 [確定],然後按一下 [下一步]
  9. 選取 [先設計資料檢視],然後按一下 [完成],以關閉 [資料來源安裝精靈] 對話方塊。
  10. 新增 [SendXMLElementResult] 欄位到表單中。
  11. 預覽表單。
  12. [傳送 XML 節點結果] 控制項中,輸入 Hello, World!
  13. [檔案] 功能表上,按一下 [送出]

    您會收到下列錯誤訊息:
    InfoPath 無法送出表單。
    表單送出時發生錯誤。

    顯示詳細資料:
    SOAP 回應指出有錯誤發生:
    伺服器無法讀取要求。--> XML 文件 1,409 中有錯誤。-->指定的轉換無效。
  14. 關閉 [預覽] 視窗,然後返回表單「設計」模式。
如果要解決這個問題,請使用本文<解決方案>一節所述的其中一種方法。
內容

文章識別碼:826989 - 最後檢閱時間:01/11/2015 05:20:26 - 修訂: 4.0

Microsoft Office InfoPath 2003, Microsoft Office InfoPath 2003, Service Pack 1 (SP1)

  • kbnosurvey kbarchive kbtshoot kbprb kbbug KB826989
意見反應