1. ホーム
  2. c#

[解決済み] JSON.Net 4.0でのJObjectとJPropertyの使い方

2022-02-27 15:23:07

質問

このフォーマットでJSONをデシリアライズしようとしています。

{
   "data": [
      {
         "installed": 1,
         "user_likes": 1,
         "user_education_history": 1,
         "friends_education_history": 1,
         "bookmarked": 1
      }
   ]
}

をこのような単純な文字列配列に変換します。

{
    "installed",
    "user_likes",
    "user_education_history",
    "friends_education_history",
    "bookmarked"
}

を使って JSON.NET 4.0

CustomCreationConverter'を使って動作させることができました。

public class ListConverter : CustomCreationConverter<List<string>>
{
public override List<string> Create(Type objectType)
{
    return new List<string>();
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    var lst = new List<string>();

    //don't care about the inital 'data' element
    reader.Read();

    while (reader.Read())
    {
        if (reader.TokenType == JsonToken.PropertyName)
        {
            lst.Add(reader.Value.ToString());
        }
    }
    return lst;
}
}

しかし、これは本当にやりすぎだと思います。特に、多くの異なる json 応答に対して 1 つを作成する場合はそうです。

を使ってみました。 JObject が、どうもうまくいかない。

List<string> lst = new List<string>();
JObject j = JObject.Parse(json_string);
foreach (JProperty p in j.SelectToken("data").Children().Children())
{
    lst.Add(p.Name);
}

何か良い方法はないでしょうか?

どのように解決するのですか?

いろいろな方法がありますが、今あるものでいいんです。他のいくつかの選択肢を以下に示します。

  • すべての子要素ではなく、配列の最初の要素を取得します。
  • 使用方法 SelectToken を使用すると、1回の呼び出しで配列の最初の要素に移動できます。

        string json = @"{
          ""data"": [
            {
              ""installed"": 1,
              ""user_likes"": 1,
              ""user_education_history"": 1,
              ""friends_education_history"": 1,
              ""bookmarked"": 1
            }
          ]
        }";
    
        JObject j = JObject.Parse(json);
    
        // Directly traversing the graph
        var lst = j["data"][0].Select(jp => ((JProperty)jp).Name).ToList();
        Console.WriteLine(string.Join("--", lst));
    
        // Using SelectToken
        lst = j.SelectToken("data[0]").Children<JProperty>().Select(p => p.Name).ToList();
        Console.WriteLine(string.Join("--", lst));