Сопоставьте пару динамических значений ключа Json без динамического или словаря c#

#c# #json #serialization #json.net

#c# #json #сериализация #json.net

Вопрос:

У меня есть json, как показано ниже

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

сейчас

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

Теперь в рамках задания я должен десериализовать использование Newtonsoft.json и не могу использовать Dictionarylt;string,floatgt; или dynamic , но напрямую десериализовать либо весь json, либо SMIFUND раздел .

Моя классовая структура ниже

 public class Broker  {  public string Date { get; set; }  public Listlt;Fundgt; 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"];  

но когда я пытаюсь выполнить преобразование списка в Fund , это приводит к ошибке десериализации значения имени

 var fundsList = JsonConvert.DeserializeObjectlt;Listlt;Fundgt;gt;(jsonObject[$"{input}"].ToString());  {input} is SMIFUND  

Ответ №1:

В общем, не использовать здесь словарь было бы плохой идеей и непрактично (ИМО), но я предполагаю, что это для школьного задания, поэтому я бы попытался подойти к этому именно так.

В вашем примере вы уже используете JObject , который работает аналогично словарю, поэтому вы можете использовать его в дальнейшем следующим образом:

 public class Broker {  public string Date { get; set; }  public Listlt;Fundgt; 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 Listlt;Fundgt;()};  brokerObject.Date = (string)jsonObject["date"];   var fundsList = JsonConvert.DeserializeObjectlt;JObjectgt;(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.

Ответ №2:

Наиболее эффективным способом было бы использовать типизированный объект c# для общения:

 var jsonDeserialized=JsonConvert.DeserializeObjectlt;BrokerDgt;(json);   var result = new Broker  {  Date = jsonDeserialized.date,  funds = jsonDeserialized.SMIFUND.Select(s =gt; new Fund { StockName = s.Key, Price = (float)Convert.ToDouble(s.Value) }).ToList()  };  public class BrokerD {  public string date { get; set; }  public Dictionarylt;string, stringgt; SMIFUND { get; set; } }  

но если вы предпочитаете медленнее, вы можете проанализировать json

 var jsonObject = JObject.Parse(json);    var result = new Broker  {  Date = jsonObject["date"].ToString(),  funds = ((JObject)jsonObject["SMIFUND"]).Properties()  .Select(s =gt; 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  }  ] }  

Комментарии:

1. Это указано в заголовке и в тексте ОП — «без динамики или словаря » . Я очень сомневаюсь, что изменение типа словаря с lt;string, floatgt; на lt;string, stringgt; кардинально меняет ситуацию здесь.

2. @GuruStron Я сожалею, но OP мог бы заявить, что сделал это вообще без какого-либо кода. Я вижу в его коде » JsonConvert. Десериализацияобъектlt;Списокlt;Фондgt;lt;Фондgt;gt;» Как вы думаете, что это такое?