C# 反序列化模式中具有其他属性的JSON数组

C# 反序列化模式中具有其他属性的JSON数组,c#,json,rest,serialization,kraken.com,C#,Json,Rest,Serialization,Kraken.com,我有一个与这个问题非常相似的问题,除了我的应用程序是C#,不幸的是我不知道如何转换解决方案。我正在尝试反序列化JSON结果,如下所示: "error":[], "result": { "MANAEUR":[ [1619042400,"1.11200","1.13488","1.08341","1.10077&q

我有一个与这个问题非常相似的问题,除了我的应用程序是C#,不幸的是我不知道如何转换解决方案。我正在尝试反序列化JSON结果,如下所示:

"error":[],
"result":
     {
        "MANAEUR":[
                [1619042400,"1.11200","1.13488","1.08341","1.10077","1.09896","58878.56534370",137],
                [1619046000,"1.09767","1.12276","1.08490","1.11097","1.10456","25343.25910419",77],

            ],
        
        "last":1619118000
    }
我使用以下类别:

public class ResponseBase
{
    [JsonProperty(PropertyName = "error")]
    public List<string> Error;
}

public class OHLCResponse : ResponseBase
{
    [JsonProperty("result")]
    public OHLCResult Result;
}

public class OHLCResult
{
    [JsonProperty("pair_names")]
    public Dictionary<string, OHLC[]> GetHistory;

    [JsonProperty("last")]
    public long Last;
}
我有一个标准的反序列化器类,它适用于我对同一API使用的所有其他调用,但我无法使此调用正常工作。当我检索OHLCResponse对象时,我没有得到错误,并且总是填充“Result.Last”,但是“Result.GetHistory”中预期的OHLC项数组总是空的/null。我知道数据已成功返回,因为我可以看到WebRequest返回的变量中的数据,然后我将其传递给反序列化器函数,所以我猜这些类的布局肯定不正确

有人能看出我做错了什么吗


非常感谢,Dave,你的JSON无效,我不得不修改它使之成为有效的JSON()。我在第二个内部数组条目之后添加了根括号并删除了逗号delimter

有效的JSON:

{
  "error":[],
  "result":
     {
        "MANAEUR":[
                [1619042400,"1.11200","1.13488","1.08341","1.10077","1.09896","58878.56534370",137],
                [1619046000,"1.09767","1.12276","1.08490","1.11097","1.10456","25343.25910419",77]
            ],
        
        "last":1619118000
    }
}
更新JSON后,我使用Visual Studio的“”从JSON生成C#对象。创建了以下类

public class RootObject
{
    [JsonProperty("error")]
    public object[] Error { get; set; }

    [JsonProperty("result")]
    public Result Result { get; set; }
}

public class Result
{
    [JsonProperty("MANAEUR")]
    public object[][] Manaeur { get; set; }

    [JsonProperty("last")]
    public int Last { get; set; }
}
对于上面的JSON和类,我使用以下内容来反序列化JSON

string json = "{\"error\":[],\"result\":{\"MANAEUR\":[[1619042400,\"1.11200\",\"1.13488\",\"1.08341\",\"1.10077\",\"1.09896\",\"58878.56534370\",137],[1619046000,\"1.09767\",\"1.12276\",\"1.08490\",\"1.11097\",\"1.10456\",\"25343.25910419\",77]],\"last\":1619118000}}";
var obj = JsonConvert.DeserializeObject<RootObject>(json);
。。。将
JsonConverter
属性添加到类中

[JsonConverter(typeof(ManaeurConverter))]
public class Result
{
    [JsonProperty("MANAEUR")]
    public object[][] Manaeur { get; set; }

    [JsonProperty("last")]
    public int Last { get; set; }
}
。。。像这样解析

string json_Manaeur = "{\"error\":[],\"result\":{\"MANAEUR\":[[1619042400,\"1.11200\",\"1.13488\",\"1.08341\",\"1.10077\",\"1.09896\",\"58878.56534370\",137],[1619046000,\"1.09767\",\"1.12276\",\"1.08490\",\"1.11097\",\"1.10456\",\"25343.25910419\",77]],\"last\":1619118000}}";
string json_Not_Manaeur = "{\"error\":[],\"result\":{\"NOTMANAEUR\":[[1619042400,\"1.11200\",\"1.13488\",\"1.08341\",\"1.10077\",\"1.09896\",\"58878.56534370\",137],[1619046000,\"1.09767\",\"1.12276\",\"1.08490\",\"1.11097\",\"1.10456\",\"25343.25910419\",77]],\"last\":1619118000}}";
            
var objManaeur = JsonConvert.DeserializeObject<RootObject>(json_Manaeur);
var objNotManaeur = JsonConvert.DeserializeObject<RootObject>(json_Not_Manaeur);
string json\u-Manaeur=“{”error\”:[],“result\”:{“Manaeur\”:[[1619042400,\'1.11200\”,\'1.13488\,\'1.08341\”,\'1.10077\,\'1.09896\,\'58878.56534370\,'137],[1619046000,\'1.09767\,'1.12276\,'1.08490\,'1.11097\,'1.104896\,'2539170],'1619145;';
字符串json\u Not\u mananeur=“{”error\”:[],\“result\”:{“notmananeur\”:[1619042400,\'1.11200\,\'1.13488\,\'1.08341\”,\'1.10077\,\'1.09896\,\'58878.56534370\,'137],'1619046000,\'1.09767\,'1.12276\,'1.08490\,'1.11097\,'1.104896\,'25377\,'1619145;';
var objManaeur=JsonConvert.DeserializeObject(json_Manaeur);
var objNotManaeur=JsonConvert.DeserializeObject(json_Not_Manaeur);

您发布的对象不是有效的JSON。外面的花括号不见了。所以我假设它应该是这样的:

"error":[],
"result":
     {
        "MANAEUR":[
                [1619042400,"1.11200","1.13488","1.08341","1.10077","1.09896","58878.56534370",137],
                [1619046000,"1.09767","1.12276","1.08490","1.11097","1.10456","25343.25910419",77],

            ],
        
        "last":1619118000
    }
{
“错误”:[],
“结果”:{
“管理者”:[
[1619042400, "1.11200", "1.13488", "1.08341", "1.10077", "1.09896", "58878.56534370", 137],
[1619046000, "1.09767", "1.12276", "1.08490", "1.11097", "1.10456", "25343.25910419", 77],
],
“最后”:1619118000
}
}
匿名反序列化 您可以使用的第一种方法是匿名反序列化,这可能有点麻烦,因为您必须反序列化两次

让我们从定义一些模型开始:

公共密封类OHLC模型
{
公共长时间{get;set;}
公共十进制开放{get;set;}
公共十进制高位{get;set;}
公共十进制低位{get;set;}
公共十进制关闭{get;set;}
公共十进制Vwap{get;set;}
公共十进制卷{get;set;}
公共整数计数{get;set;}
}
公共密封类结果模型
{
[JsonIgnore]
公共IEnumerable管理器{get;set;}
[JsonProperty(“last”)]
公共长上次{get;set;}
}
公共密封类根模型
{
[JsonProperty(“错误”)]
公共列表错误{get;set;}
[JsonProperty(“结果”)]
公共结果模型结果{get;set;}
}
如您所见,当序列化发生时,我们将忽略
Manaeur
对象

要使此方法有效,我们将执行以下操作:

var json=System.IO.File.ReadAllText(@“c:\users\andy\desktop\test.json”);
//首先,只需抓取具有混合数组的对象。
//这将创建目标对象格式的“模板”
var dto=JsonConvert.DeserializeAnonymousType(json,新
{
结果=新的
{
Manaeur=新列表()
}
});
//接下来,反序列化它的其余部分
var fullObject=JsonConvert.DeserializeObject(json);
//使用Select语句将数据传输到
fullObject.Result.Manaeur=dto.Result.Manaeur.Select(x=>newOHLCModel
{
时间=转换为64(x[0]),
Open=转换为十进制(x[1]),
高=转换为十进制(x[2]),
低=转换为十进制(x[3]),
Close=将.ToDecimal(x[4])转换为,
Vwap=转换为十进制(x[5]),
体积=转换为十进制(x[6]),
计数=将.ToInt32(x[7])
});
这不是最理想的解决方案,因为您在几个点上与模型紧密耦合。实现这一点的理想方法是定制
JsonSerializer

使用自定义JsonConverter 我们要做的第一件事是将您的
ResultModel
更改为如下所示:

"error":[],
"result":
     {
        "MANAEUR":[
                [1619042400,"1.11200","1.13488","1.08341","1.10077","1.09896","58878.56534370",137],
                [1619046000,"1.09767","1.12276","1.08490","1.11097","1.10456","25343.25910419",77],

            ],
        
        "last":1619118000
    }
公共密封类结果模型
{
[JsonConverter(typeof(ManaeurJsonConverter)),JsonProperty(“MANAEUR”)]
公共IEnumerable管理器{get;set;}
[JsonProperty(“last”)]
公共长上次{get;set;}
}
然后实现一个
JsonConverter

public sealed class ManaeurJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType) => false; // this will never get called

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var lst = JArray.Load(reader).ToObject<List<List<object>>>();
        return lst.Select(x => new OHLCModel
        {
            Time = Convert.ToInt64(x[0]),
            Open = Convert.ToDecimal(x[1]),
            High = Convert.ToDecimal(x[2]),
            Low = Convert.ToDecimal(x[3]),
            Close = Convert.ToDecimal(x[4]),
            Vwap = Convert.ToDecimal(x[5]),
            Volume = Convert.ToDecimal(x[6]),
            Count = Convert.ToInt32(x[7])
        });
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    { // we don't need to write
        throw new NotImplementedException();
    }
}
公共密封类管理器JsonConverter:JsonConverter
{
public override bool CanConvert(Type objectType)=>false;//这将永远不会被调用
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
var lst=JArray.Load(reader.ToObject();
返回lst.Select(x=>newOHLCModel
{
时间=转换为64(x[0]),
Open=转换为十进制(x[1]),
高=转换为十进制(x[2]),
低=转换为十进制(x[3]),
Close=将.ToDecimal(x[4])转换为,
Vwap=转换为十进制(x[5]),
体积=转换为十进制(x[6]),
计数=将.ToInt32(x[7])
});
}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{//我们不需要写
苏氨酸