/// <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."); }
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)); } }