Using RSO POST

RSO POST functions just like the original RS or RS POST. There should be no impact to your client or server code. However, there are enhancements to take advantage of - just a few - but they make a big difference in what you consider passing back and forth between the client and server.

Installing RSO POST

There are 7 files used in RSO POST: rs.htm, rs.asp, ObjectTransfer.asp, ObjectTransfer.htm, ObjectTransferSupport.asp, rsproxy.class, and pm.asp. They should all be installed in your _ScriptLibrary or wherever you use RS or RS POST from now. rsproxy.class is the same file distributed as part of RS POST. pm.asp is a replacement for the pm.asp that is part of the InterDev 6.0 _ScriptLibrary.  It contains updates to allow it to work with RS POST and RSO POST. 

Client Changes

RSO POST Retains the Datatype of Arguments

RS always converted all parameters to strings. So passing the number 42 resulted in the string '42' on the server.  Not so with RSO POST.  All data types are preserved in the transfer.

If you are "stringizing" your data, only to "unstringize" it on the server, stop doing that.  Your stringizing is unnecessary. This includes escape-ing strings to protect strange characters like '+', newline and carriage return.

Pass Complex Data to the Server

The biggest change (and the best) is that all manner of JS data can be passed to the server: objects, arrays, etc. RSO POST even preserves the identity of internal objects and arrays within a parameter so you can pass circular data types (like doubly-linked lists).

Server Changes

RSO POST Retains the Datatype of Arguments

If you have remote methods that take advantage of the fact that all arguments were implicitly converted to a strings, you'll have to explicitly convert nonstring arguments to strings before manipulating them. In general use, this should not cause many problems.

Pass Complex Data to the Server

If you use some form of string encoding (join/split on arrays, for example) you can eliminate this task. General datatypes (date, boolean, number, ...), Objects and Arrays of anything (including other Arrays and Objects) are directly supported by RSO POST. A one-off effect of this direct support is that the data in the array retain their datatypes.
Example: If you have an array of numbers to pass to the server.
In RS you might .join('~') the array and pass the string to the server which would .split('~') the string back out into an array. The array is not exactly the same though; the array elements are now strings and not numbers.
In RSO POST you simple pass the array of numbers.  On the server it will be an array of numbers.

Returning Values

To return a value of any type simply return it from the remote method. As with RS the value is available to the client in the return_value field of the call object.

Returning Errors and Error Values

RSO POST traps all exceptions inside remote methods and returns to the client the actual exception expression caught. You can take advantage of this and simply use throw to return an error back to the client.  There are several choices depending on how complex your returned error information needs to be. RSO POST also catches execution errors and returns those to the client. Following are examples of ways to return errors and what the client call object contains in each case. In all cases the status field contains MSRS_FAIL and in the case of an asynchronous call, the error callback (if specified) will be invoked on the client.

/* Execution Error on Server */
var i = new Object;
i.foo(); /* error */
/* On Client */
call.message : "Object doesn't support this property or method"
call.error_value : object containing all the fields from the
error - name, message, number, description,...
/* User thrown string on Server */
throw 'Invalid order number';
/* On Client */
call.message : "Invalid order number"
call.error_value : "Invalid order number"
/* User thrown non-string data on Server */
throw ['Errors occured', 1, 2, 3];
/* On Client */
call.message : null
call.error_value : ['Errors occured', 1, 2, 3]
/* User thrown custom error + data on Server */
var x = new Array;
/* fill x with error data */
throw RSError('Errors occured during execution', x);
/* On Client */
call.message : "Errors occured during execution"
call.error_value : <array of data from server variable x>

This allows you to return complex error data. This is different than returning normal data because on the client the status field of the call object will be MSRS_FAIL. The additional data returned is available to the client in a new call object field - error_value. You might use this, for example to return a collection of error objects detailing multiple errors during the execution of a remote method.
Example:

/* Server */
function DeleteOrders(arrayOfOrderIDs) {
var errors = new Array;

for (var i in arrayOfOrderIDs) {
var order = arrayOfOrderIDs[i];
try {
ado.DeleteOrder(order);
} catch (e) {
errors[errors.length] = {'ID' : order, 'Error' : e.description};
}
}
if (errors.length > 0) {
throw errors;
/* Or to provide the error data and a custom message...
throw RSError('Errors occured during processing', errors) */
}
}

/* Client */
function BtnDeleteOrders_onclick() {
var orders = GetArrayOfSelectedIDs();
var call = RSExecute("OrderCommands.asp", "DeleteOrders", orders);
if (call.status == MSRS_FAIL) {
DisplayErrors (call.error_value);
}
}