Пример #1
0
        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)
                });
            }
        }
Пример #2
0
        public void AddService(string method, Dictionary <string, Type> parameters)
        {
            var newService = new SmdService(transport, "JSON-RPC-2.0", parameters);

            Services.TryAdd(method, newService);
        }
Пример #3
0
        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);
                }
            }
        }