Over a year ago I wrote about using ArcGIS Server SOEs without SOAP. In that article, I wrote a simple JSON-RPC invoker that used reflection. Being spoiled by using custom JSON model binders in ASP.NET MVC, I was longing to see a similar thing in SOEs.
For those not familiar, the idea is to have an SOE’s IRequestHandler2.HandleStringRequest method accept a JSON string {method:”myMethod”, parameters:["param1","param2",12345]} and automatically invoke a method public string myMethod(string param1, string param2, int param3).
Reflection, however, is hardly the fastest way to dynamically invoke methods. Nate Kohari shows how to use LINQ expressions to create fast invokers for late-bound methods. Rick Strahl exposes some issues with LINQ Expression compilation speed, but in an SOE this overhead is incurred during Service startup.
// create a simple class to function as a JSON method wrapper
public class JsonMethodCall {
public string method;
public object[] parameters;
}
// use an Attribute to limit methods invoked via JSON
[AttributeUsage(AttributeTargets.Method)]
public class DispatchableAttribute : System.Attribute{ }
// mark your methods with an attribute
[Dispatchable]
public string myMethod(string param1, string param2, int param3){
return "Hello World : " + param1 + " " + param2 + " " + param3;
}
// create LINQ-based fast method invokers during SOE startup
public void Construct(IPropertySet properties){
MethodInfo[] methodInfos = this.GetType().GetMethods();
foreach (MethodInfo methodInfo in methodInfos){
if (testMethod.GetCustomAttributes(typeof(DispatchableAttribute, true).Length >0)
methods.Add(testMethod.Name, DelegateFactory.Create(testMethod));
}
}
// deserialize JSON and fast-invoke methods during SOE requests
public string HandleStringRequest(string Capabilities, string request)
{
MethodCall mc = JavaScriptConvert.DeserializeObject(request);
LateBoundMethod method;
if (method.TryGetValue(mc.method), out method)) {
JsonMethodCall jsonMethodCall = JavaScriptConvert.DeserializeObject(request);
result = methods[jsonMethodCall.method](this, jsonMethodCall.parameters);
} else return "Method name not found";
}
Problems: NewtonSoft’s “JavaScriptConvert.DeserializeObject” deserializes to certain types. Kohari’s LateboundMethod uses “Expression.Convert” for type reboxing, but it won’t handle type conversions. For instance, the example myMethod(string param1, string param2, int param3) method signature above yeild an error (DeserializeObject returns an Int64, the method expects an Int). Overall, this solution is hardly complete, but could be interesting for greenfield development.

