【问题标题】:Map Dynamic Json Key Value pair without dynamic or dictionary c#映射没有动态或字典c#的动态Json键值对
【发布时间】: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

【问题讨论】:

    标签: c# json serialization json.net


    【解决方案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>”你觉得是什么?
      猜你喜欢
      • 1970-01-01
      • 2021-06-17
      • 2013-07-31
      • 2012-06-17
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      相关资源
      最近更新 更多