我们有一位姓Null的员工。当使用姓氏作为搜索词时,我们的员工查找应用程序将被终止(现在这种情况很常见)。收到的错误(感谢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)柔性3.5动作脚本3冷聚变8

请注意,当从ColdFusion页面作为对象调用Web服务时,不会发生错误。


当前回答

将所有字符转换为其十六进制实体等效字符。在这种情况下,Null将被转换为&#4E&#75;&#6C中&#6C中;

其他回答

作为黑客,您可以考虑在客户端进行特殊处理,将“Null”字符串转换为永远不会发生的字符串,例如XXNULLXX,然后在服务器上进行转换。

它并不漂亮,但它可以解决这种边界情况的问题。

在ActionScript中对空值进行字符串化将得到字符串“null”。我的怀疑是,有人认为,因此,将字符串“NULL”解码为NULL是一个好主意,这会导致您在这里看到的破坏——可能是因为他们在传递NULL对象并在数据库中获取字符串,而他们不想这样做(所以也要确保检查这种错误)。

@doc180有正确的概念,只是他专注于数字,而最初的海报有字符串的问题。

解决方案是更改mx.rpc.xml.XMLEncoder文件。这是第121行:

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

(我查看了Flex 4.5.1 SDK;其他版本的行号可能不同。)

基本上,验证失败是因为“content为null”,因此您的参数没有添加到传出的SOAP数据包中;从而导致丢失的参数错误。

您必须扩展该类以删除验证。然后是一个巨大的滚雪球,修改SOAPEncoder以使用修改的XMLEncoder,然后修改Operation以使用修改后的SOAPEncode器,然后修改WebService以使用替换的Operation类。

我花了几个小时,但我需要继续。这可能需要一两天的时间。

您可能只需要修复XMLEncoder行,并使用自己的类进行一些猴子修补。

我还要补充一点,如果您切换到使用RemoteObject/AMF和ColdFusion,则传递null时不会出现问题。


2013年11月16日更新:

我在上次关于RemoteObject/AMF的评论中又增加了一条。如果您正在使用ColdFusion 10;然后从服务器端对象中删除对象上具有null值的财产。因此,在访问财产之前,必须检查它是否存在,否则会出现运行时错误。

检查如下:

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

这是ColdFusion 9的行为变化;其中空财产将变成空字符串。


2013年6月12日编辑

由于有一个关于如何处理null的问题,这里有一个快速示例应用程序来演示字符串“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>

跟踪输出为:

空字符串不等于使用!=的空保留字条件空字符串不等于使用==条件的空保留字空字符串不等于使用==条件的空保留字

关于xkcd,Bobby Tables网站有很好的建议,可以避免在各种语言(包括ColdFusion)的SQL查询中对用户数据(在本例中为字符串“Null”)进行不正确的解释。

从这个问题中还不清楚这是问题的根源,并且考虑到第一个答案的注释中提到的解决方案(将参数嵌入到结构中),这很可能是其他问题。

这是一个杂烩,但假设SEARCHSRING有一个最小长度,例如2个字符,在第二个字符处对SEARCHSTRING参数进行子串,并将其作为两个参数传递:SEARCHSSTRING1(“Nu”)和SEARCHSTRING2(“ll”)。在对数据库执行查询时,将它们重新连接在一起。