/// <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."); }
public async Task InvokeRequest_WithAudit() { Guid randomGuid = Guid.NewGuid(); var parameters = new RpcParameters(InvokerTests.FromRaw(randomGuid.ToString())); string methodName = nameof(TestRouteClass.GuidTypeMethod); var stringRequest = new RpcRequest("1", methodName, parameters); int startCalledCount = 0; int endCalledCount = 0; object data = new object(); DefaultRpcInvoker invoker = this.GetInvoker(methodName, configure: (config) => { config.OnInvokeStart = (context) => { startCalledCount++; context.CustomContextData = data; }; config.OnInvokeEnd = (context, response) => { endCalledCount++; Assert.Same(data, context.CustomContextData); }; }); RpcResponse?stringResponse = await invoker.InvokeRequestAsync(stringRequest); Assert.Equal(1, startCalledCount); Assert.Equal(1, endCalledCount); }
public virtual PhpValue call(Context ctx, PhpString name, PhpArray args) { string responseJson = null; try { // 创建ID RpcId rpcId = new RpcId(Guid.NewGuid().ToString()); // 将List<object>或者Dictionary<string, object>隐式转换成RpcParameters RpcParameters rpcParameters = ArrayUtil.array2collection(ctx, args); // 构建请求 RpcRequest rpcRequest = new RpcRequest(rpcId, name.ToString(ctx), rpcParameters); // 发送请求 RpcResponse rpcResponse = _client.SendRequestAsync(rpcRequest, "").Result; // 获取响应 PhpValue returnJson = JsonSerialization.json_decode(ctx, new PhpString(rpcResponse.Result.ToString()), true); return(PhpValue.Create(new PhpArray() { { new IntStringKey("id"), PhpValue.Create(rpcResponse.Id.StringValue) }, { new IntStringKey("jsonrpc"), PhpValue.Create("2.0") }, { new IntStringKey("result"), !returnJson.IsArray ? PhpValue.FromClr(rpcResponse.Result) : returnJson }, })); } catch (Exception ex) { if (ex.InnerException is RpcClientInvalidStatusCodeException) { responseJson = (ex.InnerException as RpcClientInvalidStatusCodeException)?.Content; } } return(String.IsNullOrEmpty(responseJson) ? PhpValue.False : JsonSerialization.json_decode(ctx, new PhpString(responseJson), true)); }
public async Task InvokeRequest_MethodNotFound_ErrorResponse() { var parameters = new RpcParameters(JsonBytesRpcParameter.FromRaw(1)); var stringRequest = new RpcRequest("1", "MethodNotFound", parameters); DefaultRpcInvoker invoker = this.GetInvoker(methodInfo: null); RpcResponse? response = await invoker.InvokeRequestAsync(stringRequest); Assert.NotNull(response); Assert.NotNull(response !.Error); Assert.Equal((int)RpcErrorCode.MethodNotFound, response.Error !.Code); }
public async Task InvokeRequest_StringParam_ParseAsGuidType() { Guid randomGuid = Guid.NewGuid(); var parameters = new RpcParameters(JsonBytesRpcParameter.FromRaw(randomGuid.ToString())); string methodName = nameof(TestRouteClass.GuidTypeMethod); var stringRequest = new RpcRequest("1", methodName, parameters); DefaultRpcInvoker invoker = this.GetInvoker(methodName); RpcResponse? stringResponse = await invoker.InvokeRequestAsync(stringRequest); Assert.NotNull(stringResponse); Assert.Equal(randomGuid, stringResponse !.Result); }
private static void CompareParameters(object[] parameters, RpcParameters jParameters) { if (parameters != null) { Assert.NotEqual(default(RpcParameters), jParameters); Assert.Equal(RpcParametersType.Array, jParameters.Type); Assert.Equal(parameters.Length, jParameters.ArrayValue.Length); //TODO compare types? } else { Assert.Equal(default(RpcParameters), jParameters); } }
public async Task InvokeRequest_Int64RequestParam_ConvertToInt32Param() { var parameters = new RpcParameters(JsonBytesRpcParameter.FromRaw(1L)); string methodName = nameof(TestRouteClass.IntParameter); var stringRequest = new RpcRequest("1", methodName, parameters); DefaultRpcInvoker invoker = this.GetInvoker(methodName); RpcResponse?response = await invoker.InvokeRequestAsync(stringRequest); RpcResponse resultResponse = Assert.IsType <RpcResponse>(response); Assert.NotNull(resultResponse.Result); Assert.Equal(1, resultResponse.Result); }
public async Task InvokeRequest_AsyncMethod_Valid() { var parameters = new RpcParameters(JsonBytesRpcParameter.FromRaw(1), JsonBytesRpcParameter.FromRaw(1)); string methodName = nameof(TestRouteClass.AddAsync); var stringRequest = new RpcRequest("1", methodName, parameters); DefaultRpcInvoker invoker = this.GetInvoker(methodName); RpcResponse?response = await invoker.InvokeRequestAsync(stringRequest); RpcResponse resultResponse = Assert.IsType <RpcResponse>(response); Assert.NotNull(resultResponse.Result); Assert.Equal(2, resultResponse.Result); }
internal Dictionary <RpcParameters, object> BuildInputParameters(byte[] blob) { Dictionary <RpcParameters, object> dictionary = new Dictionary <RpcParameters, object>(); object[] array = (object[])this.DeserializeObject(blob, false); if (array.Length % 2 == 0) { for (int i = 0; i < array.Length; i += 2) { RpcParameters key = (RpcParameters)this.DeserializeObject((byte[])array[i], true); object value = this.DeserializeObject((byte[])array[i + 1], true); dictionary[key] = value; } } return(dictionary); }
public async Task InvokeRequest_OptionalParameter_Valid() { string methodName = nameof(TestRouteClass.Optional); DefaultRpcInvoker invoker = this.GetInvoker(methodName); //No params specified RpcRequest stringRequest = new RpcRequest("1", methodName, parameters: null); RpcResponse?response = await invoker.InvokeRequestAsync(stringRequest); RpcResponse resultResponse = Assert.IsType <RpcResponse>(response); Assert.Null(resultResponse.Result); Assert.False(resultResponse.HasError, resultResponse.Error?.Message); //Param is empty var parameters = new RpcParameters(new IRpcParameter[0]); stringRequest = new RpcRequest("1", methodName, parameters: parameters); response = await invoker.InvokeRequestAsync(stringRequest); resultResponse = Assert.IsType <RpcResponse>(response); Assert.Null(resultResponse.Result); Assert.False(resultResponse.HasError); //Param is a string const string value = "Test"; parameters = new RpcParameters(new IRpcParameter[] { JsonBytesRpcParameter.FromRaw(value) }); stringRequest = new RpcRequest("1", methodName, parameters: parameters); response = await invoker.InvokeRequestAsync(stringRequest); resultResponse = Assert.IsType <RpcResponse>(response); Assert.NotNull(resultResponse.Result); Assert.IsType <string>(resultResponse.Result); Assert.Equal(value, (string)resultResponse.Result !); }
private RpcRequestParseResult ParseResult(ref Utf8JsonReader jsonReader, Memory <byte> bytes) { RpcId id = default; string? method = null; RpcParameters?parameters = null; string? rpcVersion = null; try { if (jsonReader.TokenType == JsonTokenType.StartObject) { jsonReader.Read(); } while (jsonReader.TokenType != JsonTokenType.EndObject) { string propertyName = jsonReader.GetString(); jsonReader.Read(); switch (propertyName) { case JsonRpcContants.IdPropertyName: switch (jsonReader.TokenType) { case JsonTokenType.String: id = new RpcId(jsonReader.GetString()); break; case JsonTokenType.Number: if (!jsonReader.TryGetInt64(out long longId)) { var idError = new RpcError(RpcErrorCode.ParseError, "Unable to parse rpc id as an integer"); return(RpcRequestParseResult.Fail(id, idError)); } id = new RpcId(longId); break; default: var error = new RpcError(RpcErrorCode.ParseError, "Unable to parse rpc id as a string or an integer"); return(RpcRequestParseResult.Fail(id, error)); } break; case JsonRpcContants.VersionPropertyName: rpcVersion = jsonReader.GetString(); break; case JsonRpcContants.MethodPropertyName: method = jsonReader.GetString(); break; case JsonRpcContants.ParamsPropertyName: RpcParameters ps; switch (jsonReader.TokenType) { case JsonTokenType.StartArray: jsonReader.Read(); var list = new List <IRpcParameter>(); while (jsonReader.TokenType != JsonTokenType.EndArray) { IRpcParameter parameter = this.GetParameter(ref jsonReader, bytes); list.Add(parameter); } //TODO array vs list? ps = new RpcParameters(list.ToArray()); break; case JsonTokenType.StartObject: jsonReader.Read(); var dict = new Dictionary <string, IRpcParameter>(); while (jsonReader.TokenType != JsonTokenType.EndObject) { string key = jsonReader.GetString(); jsonReader.Read(); IRpcParameter parameter = this.GetParameter(ref jsonReader, bytes); dict.Add(key, parameter); } ps = new RpcParameters(dict); break; default: return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request parameter format is invalid."))); } parameters = ps; break; } jsonReader.Read(); } if (string.IsNullOrWhiteSpace(method)) { return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request method is required."))); } 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'"))); } return(RpcRequestParseResult.Success(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)); } }
/// <summary> /// Writes the value of the parameters to json format /// </summary> /// <param name="writer">Json writer</param> /// <param name="value">Value to be converted to json format</param> /// <param name="serializer">Json serializer</param> public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { RpcParameters parameters = (RpcParameters)value; serializer.Serialize(writer, parameters.Value ?? new object[0]); }
private RpcRequestParseResult ParseResult(JsonElement.ObjectEnumerator objectEnumerator) { RpcId id = default; string? method = null; RpcParameters?parameters = null; string? rpcVersion = null; try { foreach (JsonProperty property in objectEnumerator) { switch (property.Name) { case JsonRpcContants.IdPropertyName: switch (property.Value.ValueKind) { case JsonValueKind.String: id = new RpcId(property.Value.GetString()); break; case JsonValueKind.Number: if (!property.Value.TryGetInt64(out long longId)) { var idError = new RpcError(RpcErrorCode.ParseError, "Unable to parse rpc id as an integer"); return(RpcRequestParseResult.Fail(id, idError)); } id = new RpcId(longId); break; default: var error = new RpcError(RpcErrorCode.ParseError, "Unable to parse rpc id as a string or an integer"); return(RpcRequestParseResult.Fail(id, error)); } break; case JsonRpcContants.VersionPropertyName: rpcVersion = property.Value.GetString(); break; case JsonRpcContants.MethodPropertyName: method = property.Value.GetString(); break; case JsonRpcContants.ParamsPropertyName: RpcParameters ps; switch (property.Value.ValueKind) { case JsonValueKind.Array: IRpcParameter[] items = property.Value .EnumerateArray() .Select(this.GetParameter) .Cast <IRpcParameter>() .ToArray(); //TODO array vs list? ps = new RpcParameters(items); break; case JsonValueKind.Object: Dictionary <string, IRpcParameter> dict = property.Value .EnumerateObject() .ToDictionary(j => j.Name, j => (IRpcParameter)this.GetParameter(j.Value)); ps = new RpcParameters(dict); break; default: return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request parameter format is invalid."))); } parameters = ps; break; } } if (string.IsNullOrWhiteSpace(method)) { return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request method is required."))); } 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'"))); } return(RpcRequestParseResult.Success(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)); } }
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)); } }