简体   繁体   English

反序列化 JSON 响应 C# object 错误

[英]Deserializing JSON Response to C# object error

What I'm doing is an API call to and turn the response into a C# object.我正在做的是一个 API 调用并将响应转换为 C# object。 I'm trying to refactor my working code https://codereview.stackexchange.com/questions/253949/api-response-json-to-c-object/ .我正在尝试重构我的工作代码https://codereview.stackexchange.com/questions/253949/api-response-json-to-c-object/ Into code that was suggested on codereview now I get the following error:现在进入 codereview 上建议的代码,我收到以下错误:

Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Candlestick' because the type requires a JSON object (e.g. {"name":"
value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be
 deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

Json Response from API: Json 来自 API 的响应:

[
    [
        1609065000000,
        "22739.71000000",
        "22795.73000000",
        "22700.39000000",
        "22779.08000000",
        "38.81782800",
        1609065899999,
        "883167.94526884",
        2261,
        "18.58965200",
        "423036.58181400",
        "0"
    ]
]

    [System.Text.Json.Serialization.JsonConverter(typeof(CandlestickConverter))]
    public class Candlestick
    {
        public long OpenTime { get; set; }
        public double Open { get; set; }
        public double High { get; set; }
        public double Low { get; set; }
        public double Close { get; set; }
        public double Volume { get; set; }
        public long CloseTime { get; set; }
        public double QuoteAssetVolume { get; set; }
        public long NumberOfTrades { get; set; }
        public double TakerBuyBaseAssetVolume { get; set; }
        public double TakerBuyQuoteAssetVolume { get; set; }
    }
   public class CandlestickConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var candle = (Candlestick) value;
            serializer.Serialize(writer ,
                new[]
                {
                    candle.OpenTime,
                    candle.Open,
                    candle.High,
                    candle.Low,
                    candle.Close,
                    candle.Volume,
                    candle.CloseTime,
                    candle.QuoteAssetVolume,
                    candle.NumberOfTrades,
                    candle.TakerBuyBaseAssetVolume,
                    candle.TakerBuyQuoteAssetVolume
                });
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
                return null;

            var candle = existingValue as Candlestick ?? new Candlestick();

            var array = JArray.Load(reader);
            
            candle.OpenTime = array.ElementAtOrDefault(0)?.ToObject<long>(serializer) ?? 0;
            candle.Open = array.ElementAtOrDefault(1)?.ToObject<double>(serializer) ?? 0;
            candle.High = array.ElementAtOrDefault(2)?.ToObject<double>(serializer) ?? 0;
            candle.Low = array.ElementAtOrDefault(3)?.ToObject<double>(serializer) ?? 0;
            candle.Close = array.ElementAtOrDefault(4)?.ToObject<double>(serializer) ?? 0;
            candle.Volume = array.ElementAtOrDefault(5)?.ToObject<double>(serializer) ?? 0;
            candle.CloseTime = array.ElementAtOrDefault(6)?.ToObject<long>(serializer) ?? 0;
            candle.QuoteAssetVolume = array.ElementAtOrDefault(7)?.ToObject<double>(serializer) ?? 0;
            candle.NumberOfTrades = array.ElementAtOrDefault(8)?.ToObject<long>(serializer) ?? 0;
            candle.TakerBuyBaseAssetVolume = array.ElementAtOrDefault(9)?.ToObject<double>(serializer) ?? 0;
            candle.TakerBuyQuoteAssetVolume = array.ElementAtOrDefault(10)?.ToObject<double>(serializer) ?? 0;

            return candle;
        }

        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Candlestick);
        }
    }

Implementation of convertion:转换的实现:

    var jsonObjectResponse = await response.Content.ReadAsStringAsync();
    var candles = JsonConvert.DeserializeObject<List<Candlestick>>(jsonObjectResponse);

I also tried var candles = JsonConvert.DeserializeObject<List<Candlestick>>($"{{{jsonObjectResponse}}}");我也试过var candles = JsonConvert.DeserializeObject<List<Candlestick>>($"{{{jsonObjectResponse}}}");

This gave next errror: Newtonsoft.Json.JsonReaderException: Invalid property identifier character: [. Path '', line 1, position 1.这给出了下一个错误: Newtonsoft.Json.JsonReaderException: Invalid property identifier character: [. Path '', line 1, position 1. Newtonsoft.Json.JsonReaderException: Invalid property identifier character: [. Path '', line 1, position 1.

The json response object is something I haven't worked with before. json 响应 object 是我以前没有使用过的东西。 I got it working but I would like some cleaner code and I'm trying to make it work as suggested as in the link I provided.我让它工作了,但我想要一些更简洁的代码,我正在努力让它按照我提供的链接中的建议工作。 Anyone got any idea what a solve would be or where I can find some more information?任何人都知道解决方案是什么,或者我可以在哪里找到更多信息?

@TomekSzpakowicz gave me the answer in his comment. @TomekSzpakowicz 在他的评论中给了我答案。 I had to register the custom converter so I added the following code in my start up file.我必须注册自定义转换器,所以我在启动文件中添加了以下代码。

            JsonConvert.DefaultSettings = () => new JsonSerializerSettings
            {
                Converters = new List<JsonConverter>
                {
                    new CandlestickConverter(),
                }
            };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM