예제 #1
0
        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));
            }
        }