web-dev-qa-db-fra.com

JObject.Parse vs JsonConvert.DeserializeObject

Quelle est la différence entre JsonConvert.DeserializeObject et JObject.Parse? Autant que je sache, les deux prennent une chaîne et se trouvent dans la bibliothèque Json.NET. Quel genre de situation rendrait l’un plus pratique que l’autre, ou s’agit-il principalement d’une préférence?

À titre de référence, voici un exemple d'utilisation des deux méthodes pour effectuer exactement la même chose: analyser une chaîne Json et renvoyer une liste de l'un des attributs Json.

public ActionResult ReadJson()
{
    string countiesJson = "{'Everything':[{'county_name':null,'description':null,'feat_class':'Civil','feature_id':'36865',"
                    +"'fips_class':'H1','fips_county_cd':'1','full_county_name':null,'link_title':null,'url':'http://www.alachuacounty.us/','name':'Alachua County'"+ ",'primary_latitude':'29.7','primary_longitude':'-82.33','state_abbreviation':'FL','state_name':'Florida'},"+
                    "{'county_name':null,'description':null,"+ "'feat_class':'Civil','feature_id':'36866','fips_class':'H1','fips_county_cd':'3','full_county_name':null,'link_title':null,'url':'http://www.bakercountyfl.org/','name':'Baker County','primary_latitude':'30.33','primary_longitude':'-82.29','state_abbreviation':'FL','state_name':'Florida'}]}";

    //Can use either JSONParseObject or JSONParseDynamic here
    List<string> counties = JSONParseObject(countiesJson);
    JSONParseDynamic(countiesJson);
    return View(counties);
}

public List<string> JSONParseObject(string jsonText)
{
    JObject jResults = JObject.Parse(jsonText);
    List<string> counties = new List<string>();
    foreach (var county in jResults["Everything"])
    {
        counties.Add((string)county["name"]);
    }
    return counties;
}

public List<string> JSONParseDynamic(string jsonText)
{
    dynamic jResults = JsonConvert.DeserializeObject(jsonText);
    List<string> counties = new List<string>();
    foreach(var county in jResults.Everything)
    {
        counties.Add((string)county.name);
    }
    return counties;
}
68
hubatish

L'API LINQ-to-JSON (JObject, JToken, etc.) permet de travailler avec JSON sans avoir besoin de connaître sa structure à l'avance. Vous pouvez désérialiser n'importe quel JSON arbitraire en utilisant JToken.Parse, Puis examiner et manipuler son contenu en utilisant d'autres méthodes JToken. LINQ-to-JSON fonctionne également bien si vous avez besoin d’une ou deux valeurs JSON (telles que le nom d’un comté).

JsonConvert.DeserializeObject, Quant à lui, est principalement destiné à être utilisé lorsque vous connaissez la structure du JSON à l'avance et que vous souhaitez effectuer une désérialisation dans des classes fortement typées. Par exemple, voici comment obtenir l'ensemble complet de données de comté de votre JSON dans une liste d'objets County.

class Program
{
    static void Main(string[] args)
    {
        string countiesJson = "{'Everything':[{'county_name':null,'description':null,'feat_class':'Civil','feature_id':'36865',"
                +"'fips_class':'H1','fips_county_cd':'1','full_county_name':null,'link_title':null,'url':'http://www.alachuacounty.us/','name':'Alachua County'"+ ",'primary_latitude':'29.7','primary_longitude':'-82.33','state_abbreviation':'FL','state_name':'Florida'},"+
                "{'county_name':null,'description':null,"+ "'feat_class':'Civil','feature_id':'36866','fips_class':'H1','fips_county_cd':'3','full_county_name':null,'link_title':null,'url':'http://www.bakercountyfl.org/','name':'Baker County','primary_latitude':'30.33','primary_longitude':'-82.29','state_abbreviation':'FL','state_name':'Florida'}]}";

        foreach (County c in JsonParseCounties(countiesJson))
        {
            Console.WriteLine(string.Format("{0}, {1} ({2},{3})", c.name, 
               c.state_abbreviation, c.primary_latitude, c.primary_longitude));
        }
    }

    public static List<County> JsonParseCounties(string jsonText)
    {
        return JsonConvert.DeserializeObject<RootObject>(jsonText).Counties;
    }
}

public class RootObject
{
    [JsonProperty("Everything")]
    public List<County> Counties { get; set; }
}

public class County
{
    public string county_name { get; set; }
    public string description { get; set; }
    public string feat_class { get; set; }
    public string feature_id { get; set; }
    public string fips_class { get; set; }
    public string fips_county_cd { get; set; }
    public string full_county_name { get; set; }
    public string link_title { get; set; }
    public string url { get; set; }
    public string name { get; set; }
    public string primary_latitude { get; set; }
    public string primary_longitude { get; set; }
    public string state_abbreviation { get; set; }
    public string state_name { get; set; }
}

Notez que Json.Net utilise l'argument de type donné à la méthode JsonConvert.DeserializeObject Pour déterminer le type d'objet à créer.

Bien sûr, si vous ne spécifiez pas de type lorsque vous appelez DeserializeObject, ou si vous utilisez object ou dynamic, alors Json.Net n’a pas d’autre choix que de désérialiser JObject. (Vous pouvez voir par vous-même que votre variable dynamique contient réellement un JObject en vérifiant jResults.GetType().FullName.). Dans ce cas, il n'y a pas beaucoup de différence entre JsonConvert.DeserializeObject Et JToken.Parse; soit vous donnera le même résultat.

74
Brian Rogers

JsonConvert.DeserializeObject présente un avantage sur JObject.Parse: il est possible d'utiliser JsonSerializerSettings personnalisé.

Cela peut être très utile, par exemple. si vous souhaitez contrôler la désérialisation des dates. Par défaut, les dates sont désérialisées en objets DateTime. Cela signifie que vous pouvez vous retrouver avec une date avec un autre fuseau horaire que celui de la chaîne json.

Vous pouvez modifier ce comportement en créant un JsonSerializerSetting et en définissant DateParseHandling sur DateParseHandling.DateTimeOffset.

Un exemple:

var json = @"{ ""Time"": ""2015-10-28T14:05:22.0091621+00:00""}";
Console.WriteLine(json);
// Result: { "Time": "2015-10-28T14:05:22.0091621+00:00" }

var jObject1 = JObject.Parse(json);
Console.WriteLine(jObject1.ToString());
// Result: { "Time": "2015-10-28T15:05:22.0091621+01:00" }

var jObject2 = Newtonsoft.Json.JsonConvert.DeserializeObject(json, 
  new Newtonsoft.Json.JsonSerializerSettings 
  { 
    DateParseHandling = Newtonsoft.Json.DateParseHandling.DateTimeOffset 
  });
Console.WriteLine(jObject2.ToString());
// Result: { "Time": "2015-10-28T14:05:22.0091621+00:00" }
21
pberggreen