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;
Другие вопросы по тегам