Hey guys,

I don't want to get into the security implications of this override, but I wanted to share it anyhow. In some dynamic languages, not all parameters have to be named specifically, which gives the developer a lot of flexibility in the method (very similar to JavaScript). All of the Ext.Direct implementations that I found generate your API Descriptor based on explicitly defined method parameters (and would then include the # of parameters, or the names of the parameters)... I ran into a situation where I didn't want to have to list every argument.... so I made this modification:

On the server side, I added the ability to annotate a method as being "non-strict" and then when my API Descriptor is generated, it includes with each action "strict: [true|false]". I then applied the following override to the client-side:

Code:
Ext.override(Ext.direct.RemotingMethod, {
    
    /**
     * @cfg strict (boolean=true) When params are specified, strict enforces
     * that only params specified in the API descriptor
     * will be included.  Settings to false enables any
     * values to be passed.
     * @type Boolean
     */
    strict: true,
    
    constructor: function(config) {
        var me = this;
        me.callOverridden([config]);
        if(config.hasOwnProperty('strict'))
            me.strict = config.strict;
    },
    
    /**
     * Takes the arguments for the Direct function and splits the arguments
     * from the scope and the callback.
     * @param {Array} args The arguments passed to the direct call
     * @return {Object} An object with 3 properties, args, callback & scope.
     */
    getCallData: function(args){
        var me = this,
            data = null,
            len  = me.len,
            params = me.params,
            callback,
            scope,
            name;
            
        // orderer params mode 
        if (me.ordered) {
            // If not in strict mode - allow any number of arguments to be sent
            // Since the'res not a defined number of arguments, we must introspect for
            // the following permutations:
            //    1:  arg1,arg2,...,argn 
            //  2:  arg1,arg2,...,argn,callback
            //  3:  arg1,arg2,...,argn,callback,scope
            if(me.strict === false) {
                len = args.length;
                // permutation 3 : (arg1,arg2,...,argn,callback,scope)
                if(len >= 2 && Ext.isFunction(args[len-2])) {
                    scope = args[len-1];
                    callback = args[len-2];
                    data = args.slice(0,len-2);
                }
                // permutation 2 : (arg1,arg2,...,argn,callback)
                else if (len >= 1 && Ext.isFunction(args[len-1])) {
                    callback = args[len-1];
                    data = args.slice(0,len-1);
                }
                // permutation 1 : (arg1,arg2,...,argn) 
                else if (len >= 1) {
                    data = args;
                }
                
            } else /* strict mode */ {
                callback = args[len];
                scope = args[len + 1];
                if (len !== 0) {
                    data = args.slice(0, len);
                }
            }
            
        } 
        
        // paramsAsHash mode
        else {
            data = Ext.apply({}, args[0]);
            callback = args[1];
            scope = args[2];
            
            // filter out any non-existent properties (if in strict mode)
            if(me.strict !== false)
            {
                for (name in data) {
                    if (data.hasOwnProperty(name)) {
                        if (!Ext.Array.contains(params, name)) {
                            delete data[name];
                        }
                    }
                }
            }
        }
        
        return {
            data: data,
            callback: callback,
            scope: scope    
        };
    }
});
Now, I am able to expose methods on the server-side, with no arguments, and my client-side can send whatever it wants.... I found this to be VERY useful for CRUD methods for model's with a large number of fields...

An example, in ColdFusion:

Server-Side:
Code:
/**
* Lightweight echo service with minimal footprint used
* for testing communication
*
* @extDirect true
*/
component displayname="EchoService"
{
     /**
     * @extDirect true
     * @extStrict false
     * @extParamsAsHash true
     */
     public string function echo()
     {
          // If both the message and author were included
          if(isDefined('arguments.message') && isDefined('arguments.author'))
               return author & ' said ' & message;
          // If just the message was defined (implies first argument)
          else if (isDefined('arguments.message'))
               return 'Somebody said ' & message;
          // no message provided
          else
               return 'Nothing was said';
     }
}
And the API Descriptor would look something like this:
Code:
     Ext.ns('EMS.server');
     EMS.server.REMOTING_API = {
          "url":"\/EMS\/src\/extdirect\/router.cfm",
          "namespace":"EMS.server",
          "type":"remoting",
          "actions":{
               "EchoService":[{"name":"echo","strict":false,"params":[]}]
          }
     };
     Ext.direct.Manager.addProvider(EMS.server.REMOTING_API);
And would allow client-side code like this:
Code:
var author='Jared',
message='This is my message',
callback=function(response) {
     alert(response);
};

// Alert should be : Jared said This is my message
EMS.server.EchoService.echo(
     // arguments object
     {
          message:message,
          author:author
     },
     // callback function
     callback
);

// Alert should be : Somebody said This is my message
EMS.server.EchoService.echo(
     // arguments object
     {
          message:message
     },
     // callback function
     callback
);

// Alert should be : Nothing was said
EMS.server.EchoService.echo({},callback);

Thoughts anyone?