web-dev-qa-db-ja.com

Json.NETを使用してキーと値のペアの配列を逆シリアル化する

次のjsonがあるとします。

[ {"id":"123", ... "data":[{"key1":"val1"}, {"key2":"val2"}], ...}, ... ]

これは大きなツリーの一部ですが、「data」プロパティを次のように逆シリアル化するにはどうすればよいですか。

List<MyCustomClass> Data { get; set; }

または

List<KeyValuePair> Data { get; set; }

または

Dictionary<string, string> Data { get; set; }

json.NETを使用していますか?どちらのバージョンでもかまいません(ただし、MyCustomClassのリストが好きです)。次のように、他のプロパティを含むクラスがすでにあります。

public class SomeData
{
   [JsonProperty("_id")]
   public string Id { get; set; }
   ...
   public List<MyCustomClass> Data { get; set; }
}

「MyCustomClass」には、2つのプロパティ(KeyとValue)のみが含まれます。 KeyValuePairConverterクラスが必要なように動作するように聞こえますが、使用方法の例を見つけることができませんでした。ありがとう。

18
pbz

最も簡単な方法は、キーと値のペアの配列を_IDictionary<string, string>_に逆シリアル化することです。

 _
public class SomeData
{
    public string Id { get; set; }

    public IEnumerable<IDictionary<string, string>> Data { get; set; }
}

private static void Main(string[] args)
{
    var json = "{ \"id\": \"123\", \"data\": [ { \"key1\": \"val1\" }, { \"key2\" : \"val2\" } ] }";

    var obj = JsonConvert.DeserializeObject<SomeData>(json);
}
_ 

しかし、それを独自のクラスに逆シリアル化する必要がある場合は、次のようになります。

 _
public class SomeData2
{
    public string Id { get; set; }

    public List<SomeDataPair> Data { get; set; }
}

public class SomeDataPair
{
    public string Key { get; set; }

    public string Value { get; set; }
}

private static void Main(string[] args)
{
    var json = "{ \"id\": \"123\", \"data\": [ { \"key1\": \"val1\" }, { \"key2\" : \"val2\" } ] }";

    var rawObj = JObject.Parse(json);

    var obj2 = new SomeData2
    {
        Id = (string)rawObj["id"],
        Data = new List<SomeDataPair>()
    };

    foreach (var item in rawObj["data"])
    {
        foreach (var prop in item)
        {
            var property = prop as JProperty;

            if (property != null)
            {
                obj2.Data.Add(new SomeDataPair() { Key = property.Name, Value = property.Value.ToString() });
            }

        }
    }
}
_ 

Valuestringであることを理解し、ToString()メソッドを呼び出します。別の複雑なクラスが存在する場合があります。

20
Boo

私はこれをやった:

[JsonConverter(typeof(MyCustomClassConverter))]
public class MyCustomClass
{
  internal class MyCustomClassConverter : JsonConverter
  {
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
      throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
      JObject jObject = JObject.Load(reader);

      foreach (var prop in jObject)
      {
        return new MyCustomClass { Key = prop.Key, Value = prop.Value.ToString() };
      }

      return null;
    }

    public override bool CanConvert(Type objectType)
    {
      return typeof(MyCustomClass).IsAssignableFrom(objectType);
    }
  }

  public string Key { get; set; }
  public string Value { get; set; }
}
2
pbz
public class Datum
{
    public string key1 { get; set; }
    public string key2 { get; set; }
}

public class RootObject
{
    public string id { get; set; }
    public List<Datum> data { get; set; }
}

このウィザードも使用しました json2csharp.com 逆シリアル化するクラスを生成しました

それを使うために

using RestSharp;
using Newtonsoft.Json;

IRestResponse restSharp= callRestGetMethodby_restSharp(api_server_url);
string jsonString= restSharp.Content;

RootObject rootObj= JsonConvert.DeserializeObject<RootObject>(jsonString);
return Json(rootObj);

restsharpでrestを呼び出す場合

    public IRestResponse callRestGetMethodby_restSharp(string API_URL)
    {
        var client = new RestSharp.RestClient(API_URL);
        var request = new RestRequest(Method.GET);
        request.AddHeader("Content-Type", "application/json");
        request.AddHeader("cache-control", "no-cache");
        IRestResponse response = client.Execute(request);
        return response;
    }

getpostman.com toolsからこの6行のレストシャープを取得することもできます