映射没有动态或字典c#的动态Json键值对

Posted

技术标签:

【中文标题】映射没有动态或字典c#的动态Json键值对【英文标题】:Map Dynamic Json Key Value pair without dynamic or dictionary c# 【发布时间】:2022-01-10 16:43:37 【问题描述】:

我有一个像下面这样的 json


    "date": "2021-12-04",
    "SMIFUND": 
        "ACC": 5.7299,
        "TATA": 5.155546,
        "RELIANCE": 108.779225
    

现在

SMIFUND ->  (input parameter to get this json result)
ACC, TATA , RELAINCE  ->  dynamic 

现在作为作业的一部分,我必须使用 Newtonsoft.json 反序列化,并且不能使用 Dictionary<string,float>dynamic,而是直接反序列化到整个 json 或 SMIFUND 部分。

下面是我的班级结构

public class Broker
    
        public string Date  get; set; 
        public List<Fund> funds get; set; 
    

public class Fund
   
       public string StockName get; set; 
       public float Price get; set; 
   

我可以将结果分成两部分

        JObject jsonObject = JObject.Parse(result);

        brokerObject.Date = (string)jsonObject["date"];

但是当我尝试将 List 转换为 Fund 时,它会给出名称值反序列化错误

var fundsList = JsonConvert.DeserializeObject<List<Fund>>(jsonObject[$"input"].ToString());

input is SMIFUND

【问题讨论】:

【参考方案1】:

一般来说,在这里不使用字典是一个坏主意,也不实用 (IMO),但我认为这是为了学校作业,所以这将是我尝试解决这个问题的方式。

在您的示例中,您已经在使用JObject,它的工作原理类似于字典,因此您可以像这样进一步使用它:

public class Broker

    public string Date  get; set; 
    public List<Fund> funds get; set; 


public class Fund

   public string StockName get; set; 
   public decimal Price get; set; 


var input = "SMIFUND"; 
var json = "\"date\": \"2021-12-04\", \"SMIFUND\":  \"ACC\": 5.7299, \"TATA\": 5.155546, \"RELIANCE\": 108.779225    ";
var jsonObject = JObject.Parse(json);
    
var brokerObject = new Broker() funds = new List<Fund>();     
brokerObject.Date = (string)jsonObject["date"];
    
var fundsList = JsonConvert.DeserializeObject<JObject>(jsonObject[$"input"].ToString());
foreach (var x in fundsList)

    var fund = new Fund();
    fund.StockName = x.Key;
    fund.Price = Decimal.Parse(x.Value.ToString()); 
    brokerObject.funds.Add(fund); 

所以基本上不是直接反序列化成一个列表,而是反序列化成一个 JObject 并以与字典相同的方式遍历它。

假设允许使用 JObject。

【讨论】:

【参考方案2】:

最有效的方法是使用类型化的 c# 对象进行对话:

    var jsonDeserialized=JsonConvert.DeserializeObject<BrokerD>(json);

    var result = new Broker
    
        Date = jsonDeserialized.date,
        funds = jsonDeserialized.SMIFUND.Select(s => new Fund  StockName = s.Key, Price = (float)Convert.ToDouble(s.Value) ).ToList()
    ;

public class BrokerD

    public string date  get; set; 
    public Dictionary<string, string> SMIFUND  get; set; 

但如果你喜欢慢一点,你可以解析一个 json

var jsonObject = JObject.Parse(json);
    
    var result = new Broker
    
        Date = jsonObject["date"].ToString(),
        funds = ((JObject)jsonObject["SMIFUND"]).Properties()
        .Select(s => new Fund  
        StockName = s.Name, Price = (float)Convert.ToDouble(s.Value)
        ).ToList()
    ;

结果


  "Date": "2021-12-04",
  "funds": [
    
      "StockName": "ACC",
      "Price": 5.7299
    ,
    
      "StockName": "TATA",
      "Price": 5.155546
    ,
    
      "StockName": "RELIANCE",
      "Price": 108.77923
    
  ]

【讨论】:

在 OP 的标题和正文中说明 - "没有动态或 字典"。我非常怀疑将字典类型从 &lt;string, float&gt; 更改为 &lt;string, string&gt; 会彻底改变这里的情况。 @GuruStron 很抱歉,但 OP 可以声明完全不需要任何代码。我可以在他的代码中看到“JsonConvert.DeserializeObject>”你觉得是什么?

以上是关于映射没有动态或字典c#的动态Json键值对的主要内容,如果未能解决你的问题,请参考以下文章

在 JSON 中使用动态多维键值对

如何在JSON格式的android动态键值对中动态获取输入数据

调试 C# 时为啥不能更改字典键值对的计数?

将控件绑定到键值对的动态集合

重温 C# 字典Dictionary类

Python字典_术语