public JsonRpcResponse Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver) { if (reader.ReadIsNull()) { return(null); } var ver = ""; var count = 0; JsonRpcId id = default; ArraySegment <byte>?resSeg = null; object res = null; ArraySegment <byte>?errSeg = null; JsonRpcError rpcErr = default; while (reader.ReadIsInObject(ref count)) { var name = reader.ReadPropertyName(); switch (name) { case "jsonrpc": ver = reader.ReadString(); break; case "result": resSeg = reader.ReadNextBlockSegment(); break; case "error": errSeg = reader.ReadNextBlockSegment(); break; case "id": try { id = ReadRpcId(ref reader, formatterResolver); } catch (JsonRpcInnerException) { throw new JsonRpcException(JsonRpcErrorCodes.InvalidMessage, Strings.GetString("core.deserialize.response.id.invalid_property")); } break; default: reader.ReadNextBlock(); break; } } if (resSeg == null && errSeg == null) { throw new JsonRpcException(JsonRpcErrorCodes.InvalidMessage, Strings.GetString("core.deserialize.response.invalid_properties"), id); } var jsonRpcFormatterResolver = formatterResolver as JsonRpcResponseFormatterResolver; var contract = jsonRpcFormatterResolver.GetContract(id); JsonReader segReader; if (resSeg.HasValue && resSeg.Value.Count > 0) { segReader = new JsonReader(resSeg.Value.Array, resSeg.Value.Offset); res = (contract?.ResultType != null) ? JsonSerializer.NonGeneric.Deserialize(contract.ResultType, ref segReader, formatterResolver) : throw new JsonRpcException(JsonRpcErrorCodes.InvalidOperation, Strings.GetString("core.deserialize.response.method.contract.undefined"), id); } if (errSeg.HasValue && errSeg.Value.Count > 0) { segReader = new JsonReader(errSeg.Value.Array, errSeg.Value.Offset); rpcErr = ReadRpcError(ref segReader, contract?.ErrorDataType ?? jsonRpcFormatterResolver.DefaultErrorDataType, formatterResolver, x => { switch (x) { case ArgumentOutOfRangeException ex: throw new JsonRpcException(JsonRpcErrorCodes.InvalidMessage, Strings.GetString("core.deserialize.response.error.code.invalid_range"), id, ex); case ArgumentNullException ex: throw new JsonRpcException(JsonRpcErrorCodes.InvalidMessage, Strings.GetString("core.deserialize.response.error.message.invalid_property"), id, ex); default: throw new JsonRpcException(JsonRpcErrorCodes.InvalidMessage, Strings.GetString("core.deserialize.response.error.invalid_type"), id, x); } }); } if (res == null && rpcErr == null || res != null && rpcErr != null) { throw new JsonRpcException(JsonRpcErrorCodes.InvalidMessage, Strings.GetString("core.deserialize.response.invalid_properties"), id); } return((rpcErr == null) ? new JsonRpcResponse(res, id) : new JsonRpcResponse(rpcErr, id)); }
public JsonRpcRequest Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver) { if (reader.ReadIsNull()) { return(null); } if (reader.GetCurrentJsonToken() != JsonToken.BeginObject) { try { reader.ReadNextBlock(); } catch { } throw new JsonRpcInnerException(JsonRpcInnerErrorCode.InvalidMessage); } var count = 0; var method = ""; object @params = null; ArraySegment <byte>?paramSeg = null; JsonRpcId id = default; Exception methodExc = null; while (reader.ReadIsInObject(ref count)) { var name = reader.ReadPropertyName(); switch (name) { case "jsonrpc": if (reader.ReadString() != "2.0") { throw new JsonRpcException(JsonRpcErrorCodes.InvalidMessage, Strings.GetString("core.deserialize.request.protocol.invalid_property")); } break; case "method": try { method = reader.ReadString(); } catch (Exception x) { methodExc = x; } break; case "params": paramSeg = reader.ReadNextBlockSegment(); break; case "id": try { id = ReadRpcId(ref reader, formatterResolver); } catch (JsonRpcInnerException) { throw new JsonRpcException(JsonRpcErrorCodes.InvalidMessage, Strings.GetString("core.deserialize.request.id.invalid_property")); } break; default: reader.ReadNext(); break; } } if (methodExc != null) { throw new JsonRpcException(JsonRpcErrorCodes.InvalidMessage, Strings.GetString("core.deserialize.request.method.invalid_property"), id); } var jsonRpcFormatterResolver = formatterResolver as JsonRpcRequestFormatterResolver; if (!jsonRpcFormatterResolver.TryGetContract(method, out var contract)) { throw new JsonRpcException(JsonRpcErrorCodes.InvalidMethod, string.Format(CultureInfo.InvariantCulture, Strings.GetString("core.deserialize.request.method.unsupported"), method), id); } if (contract == null) { throw new JsonRpcException(JsonRpcErrorCodes.InvalidOperation, string.Format(CultureInfo.InvariantCulture, Strings.GetString("core.deserialize.request.method.contract.undefined"), method), id); } JsonReader segReader; if (paramSeg.HasValue && paramSeg.Value.Count > 0) { if (contract.ParametersType == JsonRpcParametersType.None) { throw new JsonRpcException(JsonRpcErrorCodes.InvalidMessage, Strings.GetString("core.deserialize.request.params.invalid_property"), id); } segReader = new JsonReader(paramSeg.Value.Array, paramSeg.Value.Offset); @params = ReadParams(ref segReader, contract, id, formatterResolver); } switch (@params) { case IReadOnlyList <object> l: return(new JsonRpcRequest(method, id, l)); case IReadOnlyDictionary <string, object> d: return(new JsonRpcRequest(method, id, d)); default: return(new JsonRpcRequest(method, id)); } }