/// <summary>
        /// Read the json format and return the correct object type/value for it
        /// </summary>
        /// <param name="reader">Json reader</param>
        /// <param name="objectType">Type of property being set</param>
        /// <param name="existingValue">The current value of the property being set</param>
        /// <param name="serializer">Json serializer</param>
        /// <returns>The object value of the converted json value</returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            switch (reader.TokenType)
            {
            case JsonToken.StartObject:
                try
                {
                    JObject jObject = JObject.Load(reader);
                    Dictionary <string, object> dic = jObject.ToObject <Dictionary <string, JToken> >()
                                                      .ToDictionary(kv => kv.Key, kv => (object)kv.Value);
                    return(RpcParameters.FromDictionary(dic));
                }
                catch (Exception)
                {
                    throw new RpcInvalidRequestException("Request parameters can only be an associative array, list or null.");
                }

            case JsonToken.StartArray:
                var a = JArray.Load(reader).ToArray();
                return(RpcParameters.FromList(a));

            case JsonToken.Null:
                return(RpcParameters.Empty);
            }
            throw new RpcInvalidRequestException("Request parameters can only be an associative array, list or null.");
        }
示例#2
0
        private RpcRequestParseResult DeserializeRequest(JToken token)
        {
            RpcId  id      = null;
            JToken idToken = token[JsonRpcContants.IdPropertyName];

            if (idToken != null)
            {
                switch (idToken.Type)
                {
                case JTokenType.Null:
                    break;

                case JTokenType.Integer:
                case JTokenType.Float:
                    id = new RpcId(idToken.Value <double>());
                    break;

                case JTokenType.String:
                case JTokenType.Guid:
                    id = new RpcId(idToken.Value <string>());
                    break;

                default:
                    //Throw exception here because we need an id for the response
                    throw new RpcException(RpcErrorCode.ParseError, "Unable to parse rpc id as string or number.");
                }
            }
            try
            {
                string rpcVersion = token.Value <string>(JsonRpcContants.VersionPropertyName);
                if (string.IsNullOrWhiteSpace(rpcVersion))
                {
                    return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The jsonrpc version must be specified.")));
                }
                if (!string.Equals(rpcVersion, "2.0", StringComparison.OrdinalIgnoreCase))
                {
                    return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, $"The jsonrpc version '{rpcVersion}' is not supported. Supported versions: '2.0'")));
                }

                string method = token.Value <string>(JsonRpcContants.MethodPropertyName);
                if (string.IsNullOrWhiteSpace(method))
                {
                    return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request method is required.")));
                }

                RpcParameters parameters  = default;
                JToken        paramsToken = token[JsonRpcContants.ParamsPropertyName];
                if (paramsToken != null)
                {
                    switch (paramsToken.Type)
                    {
                    case JTokenType.Array:
                        if (paramsToken.Any())
                        {
                            parameters = RpcParameters.FromList(paramsToken.ToArray());
                        }
                        break;

                    case JTokenType.Object:
                        if (paramsToken.Children().Any())
                        {
                            Dictionary <string, object> dict = paramsToken.ToObject <Dictionary <string, JToken> >()
                                                               .ToDictionary(kv => kv.Key, kv => (object)kv.Value);
                            parameters = RpcParameters.FromDictionary(dict);
                        }
                        break;

                    case JTokenType.Null:
                        break;

                    default:
                        return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.ParseError, "Parameters field could not be parsed.")));
                    }
                }

                return(RpcRequestParseResult.Success(new RpcRequest(id, method, parameters)));
            }
            catch (Exception ex)
            {
                RpcError error;
                if (ex is RpcException rpcException)
                {
                    error = rpcException.ToRpcError(this.serverConfig.Value.ShowServerExceptions);
                }
                else
                {
                    error = new RpcError(RpcErrorCode.ParseError, "Failed to parse request.", ex);
                }
                return(RpcRequestParseResult.Fail(id, error));
            }
        }