public Response Handle(Request req) { Delegate handle = null; SmdService metadata = null; bool haveDelegate = this.methods.TryGetValue(req.Method, out handle); bool haveMetadata = this.smd.Services.TryGetValue(req.Method, out metadata); if (haveDelegate == false || haveMetadata == false || metadata == null || handle == null) { return(new Response() { Result = null , Error = new JsonRpcException( -32601 , "Method not found" , "The method does not exist / is not available. Method name: `" + req.Method + "`" ) , Id = req.Id }); } if (req.Params == null) // allow params element to be missing without rewriting the params counting code below. { req.Params = new Newtonsoft.Json.Linq.JArray(); } if (req.Params is ICollection == false) { return(new Response() { Result = null , Error = new JsonRpcException( -32602 , "Invalid params" , "The number of parameters could not be counted. Method name: `" + req.Method + "`" ) , Id = req.Id }); } bool isJObject = req.Params is Newtonsoft.Json.Linq.JObject; bool isJArray = req.Params is Newtonsoft.Json.Linq.JArray; bool isArray = req.Params.GetType().IsArray; object[] parameters = null; var metaDataParamCount = metadata.parameters.Count(x => x != null); var getCount = req.Params as ICollection; var loopCt = getCount.Count; var paramCount = loopCt; if (paramCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount - 1].ObjectType.Name.Contains(typeof(JsonRpcException).Name)) { paramCount++; } parameters = new object[paramCount]; if (isJArray) { var jarr = ((Newtonsoft.Json.Linq.JArray)req.Params); for (int i = 0; i < loopCt; i++) { parameters[i] = CleanUpParameter(jarr[i], metadata.parameters[i]); } } else if (isJObject) { var jo = req.Params as Newtonsoft.Json.Linq.JObject; var asDict = jo as IDictionary <string, Newtonsoft.Json.Linq.JToken>; for (int i = 0; i < loopCt; i++) { if (asDict.ContainsKey(metadata.parameters[i].Name) == false) { return(new Response() { Error = new JsonRpcException( -32602 , "Invalid params" , string.Format( "Named parameter '{0}' was not present." , metadata.parameters[i].Name ) + ". Method name: `" + req.Method + "`" ) , Id = req.Id }); } parameters[i] = CleanUpParameter(jo[metadata.parameters[i].Name], metadata.parameters[i]); } } else if (isArray) { var ps = req.Params as object[]; for (int i = 0; i < loopCt; i++) { parameters[i] = CleanUpParameter(ps[i], metadata.parameters[i]); } } if (parameters.Length != metaDataParamCount) { return(new Response() { Error = new JsonRpcException( -32602 , "Invalid params" , string.Format( "Expecting {0} parameters, and received {1}" , metadata.parameters.Length , parameters.Length ) + ". Method name: `" + req.Method + "`" ) , Id = req.Id }); } try { var results = handle.DynamicInvoke(parameters); return(new Response() { Id = req.Id, Result = results }); } catch (Exception ex) { if (ex is TargetParameterCountException) { return(new Response() { Id = req.Id, Error = new JsonRpcException(-32602, "Invalid params", ex) }); } // We really dont care about the TargetInvocationException, just pass on the inner exception if (ex is JsonRpcException) { return(new Response() { Id = req.Id, Error = ex as JsonRpcException }); } if (ex.InnerException != null && ex.InnerException is JsonRpcException) { return(new Response() { Id = req.Id, Error = ex.InnerException as JsonRpcException }); } else if (ex.InnerException != null) { return(new Response() { Id = req.Id, Error = new JsonRpcException(-32603, "Internal Error", ex.InnerException) }); } return(new Response() { Id = req.Id, Error = new JsonRpcException(-32603, "Internal Error", ex) }); } }
public void AddService(string method, Dictionary <string, Type> parameters) { var newService = new SmdService(transport, "JSON-RPC-2.0", parameters); Services.TryAdd(method, newService); }
public bool Handle(Response res) { long _id = -1; if (res.Id != null) { try { _id = Convert.ToInt64(res.Id); } catch {} } if (_id == -1) { return(false); } Delegate handle = null; SmdService metadata = null; bool haveCallback = this.requestCallbacks.TryGetValue(_id, out handle); bool haveMetadata = this.smdService.TryGetValue(_id, out metadata); if (haveCallback == false || haveMetadata == false || handle == null || metadata == null) { return(false); } if (res.Error != null) { { Delegate temp; requestCallbacks.TryRemove(_id, out temp); } { SmdService temp; smdService.TryRemove(_id, out temp); } return(true); } object[] parameters = null; var metaDataParamCount = metadata.parameters.Count(x => x != null); if (metaDataParamCount != (res.Result == null ? 0 : 1)) { throw new JsonRpcException( -32602 , "Invalid params" , string.Format( "Expecting {0} parameters, and received {1}" , metadata.parameters.Length , (res.Result == null ? 0 : 1) ) ); } if (res.Result != null) { parameters = new object[1]; parameters[0] = CleanUpParameter(res.Result, metadata.parameters[0]); } else { parameters = new object[0]; } try { handle.DynamicInvoke(parameters); return(true); } catch (Exception ex) { if (ex is TargetParameterCountException) { throw new JsonRpcException(-32602, "Invalid params", ex); } // We really dont care about the TargetInvocationException, just pass on the inner exception if (ex is JsonRpcException) { throw ex; } if (ex.InnerException != null && ex.InnerException is JsonRpcException) { throw ex.InnerException as JsonRpcException; } else if (ex.InnerException != null) { throw new JsonRpcException(-32603, "Internal Error", ex.InnerException); } throw new JsonRpcException(-32603, "Internal Error", ex); } finally { { Delegate temp; requestCallbacks.TryRemove(_id, out temp); } { SmdService temp; smdService.TryRemove(_id, out temp); } } }