Pregunta ¿Cómo pasar "nulo" (un verdadero apellido) a un servicio web SOAP en ActionScript 3?


Tenemos un empleado cuyo apellido es Null. Nuestra aplicación de búsqueda de empleados se cancela cuando se usa ese apellido como término de búsqueda (que a menudo sucede ahora). El error recibido (¡gracias Fiddler!) Es:

<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>

Lindo, ¿eh?

El tipo de parámetro es string.

Estoy usando:

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

Tenga en cuenta que el error no ocurre al llamar al servicio web como un objeto de una página de ColdFusion.


4474
2017-12-16 00:42


origen


Respuestas:


 Rastreándolo

Al principio pensé que esto era un error de coerción donde null estaba siendo coaccionado a "null" y una prueba de "null" == null pasaba. No es. Estaba cerca, pero estaba muy, muy mal. ¡Lo siento por eso!

Desde entonces he hecho muchas jugueteando en wonderfl.net y rastreando a través del código en mx.rpc.xml.*. En la línea 1795 de XMLEncoder (en la fuente 3.5), en setValue, toda la codificación XMLE se reduce a

currentChild.appendChild(xmlSpecialCharsFilter(Object(value)));

que es esencialmente lo mismo que:

currentChild.appendChild("null");

Este código, según mi violín original, devuelve un elemento XML vacío. ¿Pero por qué?

 Porque

De acuerdo con el comentarista Justin Mclean sobre el informe de error FLEX-33664, el siguiente es el culpable (ver las dos últimas pruebas en mi violín que verifican esto):

var thisIsNotNull:XML = <root>null</root>;
if(thisIsNotNull == null){
    // always branches here, as (thisIsNotNull == null) strangely returns true
    // despite the fact that thisIsNotNull is a valid instance of type XML
}

Cuando currentChild.appendChild se pasa la cuerda "null", primero lo convierte en un elemento raíz de XML con texto null, y luego prueba ese elemento contra el literal nulo. Esta es una prueba de igualdad débil, por lo que el XML que contiene null se fuerza al tipo nulo, o el tipo nulo se coacciona a un elemento root xml que contiene la cadena "null", y la prueba pasa donde podría fallar. Una solución podría ser usar siempre igualdad estricta pruebas al verificar XML (o cualquier cosa, realmente) para "nulidad".

Solución

La única solución razonable que se me ocurre, además de corregir este error en cada maldita versión de ActionScript, es probar campos para "null" y escapar de ellos como Valores CDATA. 

Los valores CDATA son la forma más adecuada de modificar un valor de texto completo que de lo contrario causaría problemas de codificación / descodificación. La codificación hexadecimal, por ejemplo, está pensada para caracteres individuales. Los valores de CDATA son preferidos cuando se está escapando el texto completo de un elemento. La razón principal de esto es que mantiene la legibilidad humana.


1049
2017-08-01 17:31



Sobre el nota xkcd, el Sitio web de Bobby Tables tiene buenos consejos para evitar la interpretación incorrecta de los datos del usuario (en este caso, la cadena "Nulo") en las consultas SQL en varios idiomas, incluidos Fusión fría.

No está claro a partir de la pregunta que esta es la fuente del problema, y ​​dada la solución observada en un comentario a la primera respuesta (incrustando los parámetros en una estructura), parece probable que fuera otra cosa.


285
2018-04-27 20:00



El problema podría estar en el codificador SOAP de Flex. Intente extender el codificador SOAP en su aplicación Flex y depure el programa para ver cómo se maneja el valor nulo. Mi conjetura es que pasó como Yaya (No un número). Esto ensuciará el proceso de asignación de mensajes SOAP en algún momento (más notablemente en JBoss 5 servidor ...). Recuerdo extender el codificador SOAP y realizar una comprobación explícita de cómo se maneja NaN.

(En una nota al margen, ¿se espera que haga algo útil si la identificación del empleado es nula? ¿No es un problema de validación? Podría estar equivocado, ya que apenas conozco el requisito ...)


235
2018-01-16 08:13



@doc_180 tenía el concepto correcto, excepto que se centra en los números, mientras que el póster original tenía problemas con las cadenas.

La solución es cambiar el mx.rpc.xml.XMLEncoder archivo. Esta es la línea 121

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

[Miré a Flex 4.5.1 SDK; los números de línea pueden diferir en otras versiones]

Básicamente, la validación falla porque 'el contenido es nulo' y, por lo tanto, su argumento no se agrega al paquete SOAP saliente; lo que causa el error de parámetro faltante.

Tienes que extender esta clase para eliminar la validación. Luego hay una gran bola de nieve en la cadena, modificando SOAPEncoder para usar su XMLEncoder modificado, y luego modificando Operation para usar su SOAPEncoder modificado y luego moidfying WebService para usar su clase de Operación alternativa.

Pasé unas horas en él, pero necesito seguir adelante. Probablemente llevará uno o dos días.

Es posible que solo arregles la línea XMLEncoder y hagas algunos parches para usar tu propia clase.

También agregaré que si cambia a usar RemoteObject / AMF con ColdFusion, el nulo se pasa sin problemas.


11/16/2013 actualización:

Tengo una adición más reciente a mi último comentario sobre RemoteObject / AMF. Si está usando CF10; a continuación, las propiedades con un valor nulo en un objeto se eliminan del objeto del lado del servidor. Por lo tanto, debe verificar la existencia de las propiedades antes de acceder a ellas o obtendrá un error de tiempo de ejecución. Marque de esta manera:

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

Este es un cambio en el comportamiento de CF9; donde las propiedades nulas se convertirían en cadenas vacías.


Editar 12/6/2013

Dado que había una pregunta acerca de cómo se tratan los nulos aquí hay una aplicación de muestra rápida para demostrar cómo una cadena "nula" se relacionará con la palabra reservada nula.

<?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>

La salida de rastreo es:

cadena nula no es igual a palabra reservada nula usando la condición! =

cadena nula no es igual a palabra reservada nula usando la condición ==

cadena nula no es igual a palabra reservada nula usando la condición ===


125
2018-05-03 15:51



Traduzca todos los caracteres en sus equivalentes de entidad hexagonal. En este caso, Null se convertiría en &#4E;&#75;&#6C;&#6C;


62
2018-04-30 19:03



Stringifying a null valor en ActionScript dará la cadena "NULL". Mi sospecha es que alguien ha decidido que, por lo tanto, es una buena idea decodificar la cadena "NULL" como null, causando la rotura que ves aquí, probablemente porque estaban pasando null objetos y obtener cadenas en la base de datos, cuando no querían eso (así que asegúrese de buscar ese tipo de error también).


49
2018-04-28 20:15



Como un truco, podría considerar tener un manejo especial en el lado del cliente, convirtiendo la cadena 'nula' a algo que nunca ocurrirá, por ejemplo, XXNULLXX y la conversión de nuevo en el servidor.

No es bonito, pero puede resolver el problema para un caso límite.


36
2018-04-28 08:43



Bueno, supongo que la implementación de Flex de SOAP Encoder parece serializar valores nulos incorrectamente. Serializarlos como un String Null no parece ser una buena solución. La versión formalmente correcta parece ser pasar un valor nulo como:

<childtag2 xsi:nil="true" />

Entonces, el valor de "nulo" no sería más que una cadena válida, que es exactamente lo que está buscando.

Supongo que arreglar esto en Apache Flex no debería ser tan difícil de hacer. Recomendaría abrir una edición de Jira o contactar a los tipos de la lista de correo apache-flex. Sin embargo, esto solo arreglaría el lado del cliente. No puedo decir si ColdFusion podrá trabajar con valores nulos codificados de esta manera.

Ver también la publicación de blog de Radu Cotescu Cómo enviar valores nulos en las solicitudes de soapUI.


30
2017-07-17 07:56



Es un kludge, pero suponiendo que hay una longitud mínima para SEARCHSTRING, por ejemplo, 2 caracteres, substring el SEARCHSTRING parámetro en el segundo carácter y pasarlo como dos parámetros en su lugar: SEARCHSTRING1 ("Nu") y SEARCHSTRING2 ("ll").  Concatenate volver a juntarlos al ejecutar la consulta en la base de datos.


21
2018-04-28 19:48