LINQ to JSON - ошибка Newtonsoft.Json.Linq.JProperty
Вот моя строка JSON:
string json = @"{
'?xml' : {
'@version' : '1.0',
'@encoding' : 'UTF-8'
},
'DataFeed' : {
'@FeedName' : 'AdminData',
'Issuer' : {
'id' : '95',
'name' : 'Apple',
'symbol' : 'AAPL'
}
}
}";
Когда я пытаюсь сделать следующий запрос LINQ:
JObject feed = JObject.Parse(json);
var compInfo = feed["DataFeed"]["Issuer"]
.Select(c => c["name"]);
Я получаю следующую ошибку:
`Cannot access child value on Newtonsoft.Json.Linq.JProperty.`
Тем не менее, следующее работает нормально:
var test1 = feed["DataFeed"]["Issuer"]["name"];
Есть идеи, почему я не могу использовать LINQ для этой строки json?
2 ответа
Подумайте, что такое ваш JSON. Вы выбираете из словаря, поэтому результат в LINQ является свойством. Затем вы пытаетесь получить доступ к "имени" для свойства, которое не имеет смысла, что приводит к ошибке.
У вас уже есть рабочий код:
var test1 = feed["DataFeed"]["Issuer"]["name"];
Вы можете получить желаемое значение, используя два метода:
Способ 1:
Сначала вам нужен актерский состав из JToken
к JObject
поскольку значение "Эмитент" является объектом:
var compInfo = (JObject)feed["DataFeed"]["Issuer"];
Затем переберите все свойства, чтобы найти свойство с именем "Name", и получите его значение в виде строки:
var str = compInfo.Properties().First(x => x.Name == "name").ToObject<string>();
// str will contain the value 'Apple'.
Способ 2:
Вы также можете десериализовать JSON в объект, который легче обрабатывать. Для этого сначала вам нужно создать объект.net, "эквивалентный" вашему JSON . Вы можете использовать Visual Studio, чтобы сгенерировать их для вас из меню "Правка" -> "Специальная вставка" -> "Вставить JSON в качестве классов" или использовать веб-сайт, такой как http://jsonutils.com/
public class Xml
{
[JsonProperty("@version")]
public string Version { get; set; }
[JsonProperty("@encoding")]
public string Encoding { get; set; }
}
public class Issuer
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("symbol")]
public string Symbol { get; set; }
}
public class DataFeed
{
[JsonProperty("@FeedName")]
public string FeedName { get; set; }
[JsonProperty("Issuer")]
public Issuer Issuer { get; set; }
}
public class RootJsonObject
{
[JsonProperty("?xml")]
public Xml Xml { get; set; }
[JsonProperty("DataFeed")]
public DataFeed DataFeed { get; set; }
}
Тогда все, что вам нужно сделать, чтобы получить имя эмитента, это:
var feed = JsonConvert.DeserializeObject<RootJsonObject>(json);
var issuer = feed.DataFeed.Issuer.Name;