web-dev-qa-db-fra.com

Désérialiser un tableau de paires clé-valeur à l'aide de Json.NET

Étant donné le json suivant:

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

cela fait partie d'un arbre plus grand, comment puis-je désérialiser la propriété "data" en:

List<MyCustomClass> Data { get; set; }

ou

List<KeyValuePair> Data { get; set; }

ou

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

utiliser Json.NET? Soit la version fera (je préfère la liste de MyCustomClass cependant). J'ai déjà une classe qui contient d'autres propriétés, comme celle-ci:

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

où "MyCustomClass" n'inclut que deux propriétés (Key et Value). J'ai remarqué qu'il existe une classe KeyValuePairConverter qui semble pouvoir faire ce dont j'ai besoin, mais je n'ai pas été en mesure de trouver un exemple d'utilisation. Merci. 

14
pbz

Le moyen le plus simple est de désérialiser un tableau de paires clé-valeur en 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);
}

Mais si vous avez besoin de désérialiser cela dans votre propre classe, cela peut ressembler à ça:


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() });
            }

        }
    }
}

Voyez que je sais que Value est string et que j'appelle ToString(), il peut y avoir une autre classe complexe.

18
Boo

J'ai fini par faire ceci:

[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; }
}

j'ai aussi utilisé cet assistant json2csharp.com pour générer une classe pour la désérialisation 

pour utiliser cette 

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);

si vous appelez repos par repos

    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;
    }

vous pouvez également obtenir cette ligne de 6 restesharp de getpostman.fr tools

0