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

Map Dynamic Json Key Value pair without dynamic or dictionary c#

我有一个 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 部分 .

我的class结构如下

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# 对象进行对话:

    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
    }
  ]
}

一般来说,在这里不使用字典是个坏主意,也不实用(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 并以与 Dictionary 相同的方式遍历它。

假设允许使用 JObject。