[Flex] 如何在ActionScript 3中將“Null”(真正姓氏!)傳遞給SOAP Web服務?


Answers

xkcd筆記中Bobby Tables網站提供了很好的建議,可以避免在包括ColdFusion在內的各種語言的SQL查詢中錯誤地解釋用戶數據(在本例中為字符串“Null”)。

從問題中不清楚這是問題的根源,並且在第一個答案(將參數嵌入到結構中)的評論中給出解決方案中提到的解決方案時,似乎可能是其他問題。

Question

我們有一位姓氏為空的員工。 我們的員工查詢應用程序在使用該姓氏作為搜索詞時(這種情況現在經常發生)被終止。 收到的錯誤(謝謝Fiddler!)是:

<soapenv:Fault>
   <faultcode>soapenv:Server.userException</faultcode>
   <faultstring>coldfusion.xml.rpc.CFCInvocationException: [coldfusion.runtime.MissingArgumentException : The SEARCHSTRING parameter to the getFacultyNames function is required but was not passed in.]</faultstring>

很可愛吧?

參數類型是string

我在用:

  • WSDL(SOAP)
  • Flex 3.5
  • ActionScript 3
  • ColdFusion 8

請注意,從ColdFusion頁面將webservice作為對象調用時,不會發生錯誤。




@ doc_180有正確的概念,除了他專注於數字,而原始的海報有字符串的問題。

解決方案是更改mx.rpc.xml.XMLEncoder文件。 這是第121行

    if (content != null)
        result += content;

[我看了一下Flex 4.5.1 SDK; 行號可能在其他版本中有所不同]

基本上,驗證因'內容為空'而失敗,因此您的參數不會添加到傳出的SOAP數據包中; 從而導致缺少參數錯誤。

你必須擴展這個類來刪除驗證。 然後,鏈上出現一個大大的雪球,修改SOAPEncoder以使用您的修改的XMLEncoder,然後修改操作以使用您的修改的SOAPEncoder,然後將WebService模糊化以使用您的備用操作類。

我花了幾個小時,但需要繼續前進。 這可能需要一兩天。

您可能只需修復XMLEncoder行並修改一些猴子來使用自己的類。

我還會補充一點,如果您切換到使用ColdFusion的RemoteObject / AMF,則null傳遞沒有問題。

11/16/2013更新

我最近還有一個關於RemoteObject / AMF的評論。 如果你使用CF10; 那麼對像上的空值屬性將從服務器端對像中刪除。 所以,你必須在訪問它之前檢查屬性的存在,否則你會得到一個運行時錯誤。 像這樣檢查:

<cfif (structKeyExists(arguments.myObject,'propertyName')>
 <!--- no property code --->
<cfelse>
 <!--- handle property  normally --->
</cfif>

這是CF9行為的變化; null屬性將變成空字符串。

編輯12/6/2013

由於存在關於如何處理空值的問題,因此這裡是一個快速示例應用程序,用於演示如何將字符串“null”與保留字null關聯起來。

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" initialize="application1_initializeHandler(event)">
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            protected function application1_initializeHandler(event:FlexEvent):void
            {
                var s :String = "null";
                if(s != null){
                    trace('null string is not equal to null reserved word using the != condition');
                } else {
                    trace('null string is equal to null reserved word using the != condition');
                }

                if(s == null){
                    trace('null string is equal to null reserved word using the == condition');
                } else {
                    trace('null string is not equal to null reserved word using the == condition');
                }

                if(s === null){
                    trace('null string is equal to null reserved word using the === condition');
                } else {
                    trace('null string is not equal to null reserved word using the === condition');
                }

            }

        ]]>
    </fx:Script>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
</s:Application>

跟踪輸出是:

空字符串不等於使用!=條件的空保留字

空字符串不等於使用==條件的空保留字

空字符串不等於使用===條件的空保留字




那麼,我猜Flex編碼器的Flex實現似乎錯誤地序列化了空值。 將它們序列化為String Null似乎不是一個好的解決方案。 正式的正確版本似乎是傳遞一個空值作為:

<childtag2 xsi:nil="true" />

所以“Null”的值只會是一個有效的字符串,這正是你正在尋找的。

我想在Apache Flex中修復這個問題不應該很難完成。 我會建議打開Jira問題或聯繫apache-flex郵件列表的人員。 但是,這只能解決客戶端問題。 我不能說ColdFusion是否能夠以這種方式編碼空值。

另請參閱Radu Cotescu的博客文章如何在soapUI請求中發送空值




ActionScriptnull值進行字符串化將會給出字符串"NULL" 。 我懷疑有人已經決定,因此,將字符串"NULL"解碼為null是一個好主意,這會導致您在此看到的破壞 - 可能是因為它們傳入null對象並在數據庫中獲取字符串,他們不希望這樣(所以一定要檢查那種錯誤)。