CURRENT PROJECTS
loading
_a=%5B%27first%27%2C%27second%27%5D&_f=com.overset.Util.echoArgs_a serves as the JSON serialized argument array of strings, i.e. ['arg1','arg2']
{"_s":"","_m":"","_d":""}_s Is the status of the function response; ["OK","ERR"]
<%@ Page Language="C#" AutoEventWireup="true" Trace="false" Debug="false" EnableSessionState="false" ValidateRequest="false" %> <%@ Assembly Name = "LitJson" %> <%@ Import Namespace = "LitJson" %> <%@ Import Namespace = "System.Globalization" %> <%@ Import Namespace = "System.Reflection" %> <script runat="server"> /// <summary> /// container class to instantiate the core return structure /// </summary> public class ajaxReturnStruct { public Hashtable retStr = new Hashtable(); public ajaxReturnStruct (string ajaxStatus, object ajaxData) { this.retStr["_s"] = ajaxStatus; this.retStr["_d"] = ajaxData; this.retStr["_m"] = ""; } public ajaxReturnStruct (string ajaxStatus, object ajaxData, string ajaxMessage) { this.retStr["_s"] = ajaxStatus; this.retStr["_d"] = ajaxData; this.retStr["_m"] = ajaxMessage; } } /// <summary> /// new custom Exception class so that we can properly handle exceptions from remote reflection method calls /// </summary> public class ajaxException : Exception { public string ajaxStatus; public string stackTrace; public ajaxException() { this.ajaxStatus = "err"; this.stackTrace = ""; } public ajaxException(string ajaxMessage) : base(ajaxMessage) { this.ajaxStatus = "err"; this.stackTrace = ""; } public ajaxException(string ajaxExStatus, string ajaxExMessage) : base(ajaxExMessage) { this.ajaxStatus = ajaxExStatus; this.stackTrace = ""; } public ajaxException(string ajaxExStatus, string ajaxExData, string ajaxExMessage) : base(ajaxExMessage) { this.ajaxStatus = ajaxExStatus; this.stackTrace = ajaxExData; } } /// <summary> /// This is the core Page_Load function that drives the AJAX handling of remote methods via reflection /// </summary> protected void Page_Load(object sender, System.EventArgs e) { if ( Request.Form["_f"] != null && Request.Form["_a"] != null ) { string[] assmQNameArray; string assmQName; JsonData parseData; Type dynType; object foundObj; Hashtable invokeMeth; string catchMethName; object[] invArgs = new object[1]; // instantiate the correct [namespace.assembly.method,assembly] via reflection try { // now parse actual data from JSON to native .net object parseData = JsonMapper.ToObject(Request.Form["_a"]); // fetch the AssemblyQualifiedName from the function string in the POST vars assmQNameArray = Request.Form["_f"].Split(".".ToCharArray()); assmQName = String.Join(".", assmQNameArray, 0, (assmQNameArray.Length - 1) ); // attempt to find function - throw on error and ignore case dynType = Type.GetType(assmQName + "," + assmQName, true, true); // create instance of Type found - nonPublic=true foundObj = Activator.CreateInstance(dynType, true); } catch (Exception cEx) { throw(new ajaxException("err", "Cannot find dynamic function -- " + cEx.Message)); } // build the arguments array and assume the arguments will always be a string if ( parseData.IsArray ) { invArgs = new object[parseData.Count]; for ( int pdI=0; pdI < parseData.Count; pdI++ ) { if ( parseData[pdI].IsBoolean ) invArgs[pdI] = (bool)parseData[pdI]; if ( parseData[pdI].IsDouble ) invArgs[pdI] = (double)parseData[pdI]; if ( parseData[pdI].IsInt ) invArgs[pdI] = (int)parseData[pdI]; if ( parseData[pdI].IsLong ) invArgs[pdI] = (long)parseData[pdI]; if ( parseData[pdI].IsString ) invArgs[pdI] = (string)parseData[pdI]; } } else { throw(new ajaxException("err", "Data must be sent as 1D array of simple data types.")); } // attempt to execute the remote method via reflection try { invokeMeth = (Hashtable) dynType.InvokeMember( assmQNameArray[assmQNameArray.Length - 1], BindingFlags.InvokeMethod, null, foundObj, invArgs ); } catch (TargetInvocationException tie) { // To discover the real cause of a remote Exception you must catch TargetInvocationException and examine the inner exception. throw(new ajaxException("err", tie.InnerException.StackTrace.ToString(), "Unexpected error calling dynamic function -- " + tie.InnerException.Message.ToString())); } Response.AddHeader("Content-Type", "text/javascript"); // prepend the escaping comments Response.Write("/****/\n"); // build response envelope ajaxReturnStruct aRet = new ajaxReturnStruct((string)invokeMeth["_s"], (string)invokeMeth["_d"], (string)invokeMeth["_m"]); // serialize response envelope and write to the response Response.Write( JsonMapper.ToJson( aRet.retStr ) ); } else { throw(new ajaxException("err", "You must include the _f (function) and _a (arguments) arguments in the POST data.")); } } /// <summary> /// This will allow for the Page directive to handle errors and return them to the client in the AJAX+JSON format /// </summary> public void Page_Error(object sender, System.EventArgs e) { Response.Clear(); // ensure we escape any prior sent javascript comments (paranoid) Response.Write("/****/\n"); ajaxReturnStruct retStr; // handle the display of our custom ajaxEception object if ( Server.GetLastError().GetBaseException().GetType() == typeof(ajaxException) ) { ajaxException objErr = (ajaxException)Server.GetLastError().GetBaseException(); retStr = new ajaxReturnStruct(objErr.ajaxStatus, objErr.stackTrace, objErr.Message.ToString()); } else { Exception objErr = Server.GetLastError().GetBaseException(); retStr = new ajaxReturnStruct("err", objErr.StackTrace.ToString(), objErr.Message.ToString()); } Response.AddHeader("Content-Type", "text/javascript"); Response.Write( (string)JsonMapper.ToJson( retStr.retStr ) ); Server.ClearError(); } </script>
// csc.exe /nologo /t:library /out:Bin\com.overset.Util.dll /r:Bin\LitJson.dll com.overset.Util.cs namespace com.overset { using System; using System.Collections; using LitJson; public class Util { public Hashtable retStr; /// <summary> /// constructor creates return structure object /// </summary> public Util () { this.retStr = new Hashtable(); } /// <summary> /// sets the data in the RetStruct to a string /// of the 2 arguments appended together /// </summary> public object echoArgs (string arg1, string arg2) { this.retStr["_s"] = "OK"; this.retStr["_d"] = arg1 + arg2; this.retStr["_m"] = ""; return this.retStr; } } }
<html> <head> <script language="JavaScript" type="text/javascript" src="jquery.js"></script> <script> $(document).ready( function () { $.ajax({ data: '&_f=com.overset.Util.echoArgs&_a=[\'first\',\'second\']', dataType: 'json', cache: false, success: function(result, textStatus) { alert( 'status: ' + result._s + '\n' + 'data: ' + result._d + '\n' + 'message: ' + result._m); }, type: 'POST', url: 'ah.aspx' }); }); </script> </head> </html>
&_f=com.overset.Util.echoArgs&_a=%5B%27first%27%2C%27second%27%5DAnd should get the following response:
Content-Type: text/javascript; charset=utf-8 /****/ {"_s":"OK","_m":"","_d":"firstsecond"}