2014-05-14 6 views
37

Was ist der Unterschied zwischen JsonConvert.DeserializeObject und JObject.Parse? Soweit ich das beurteilen kann, nehmen beide eine Zeichenfolge und sind in der Json.NET-Bibliothek. Welche Art von Situation würde einen bequemer als den anderen machen, oder ist es hauptsächlich nur Vorliebe?JObject.Parse vs JsonConvert.DeserializeObject

als Referenz, hier ist ein Beispiel für mich beide genau das Gleiche zu tun mit - einen JSON-String analysiert und eine Liste von einem der Json-Attribute.

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

Antwort

40

Die LINQ-to-JSON API (JObject, JToken, etc.) existiert mit JSON arbeiten kann, ohne seine Struktur im voraus wissen zu müssen. Sie können jede beliebige JSON deserialisieren JToken.Parse verwenden, dann prüfen und seinen Inhalt mit anderen JToken Methoden manipulieren. LINQ-zu-JSON funktioniert auch gut, wenn Sie nur einen oder zwei Werte aus dem JSON benötigen (z. B. den Namen eines Countys).

JsonConvert.DeserializeObject ist dagegen hauptsächlich dazu gedacht, verwendet zu werden, wenn Sie die Struktur des JSON im Voraus kennen und in stark typisierte Klassen deserialisieren möchten. Zum Beispiel erhalten Sie hier die vollständigen Länderdaten aus Ihrem JSON in eine Liste von County Objekten.

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

Beachten Sie, dass Json.Net den Typ Argument der JsonConvert.DeserializeObject Methode gegeben verwendet, um zu bestimmen, welche Art von Objekt zu erstellen.

Natürlich, wenn Sie keinen Typ angeben, wenn Sie DeserializeObject anrufen, oder Sie verwenden object oder dynamic, dann hat Json.Net keine andere Wahl als eine JObject deserialisieren in. (Sie können selbst sehen, dass Ihre dynamische Variable enthält tatsächlich ein JObject von jResults.GetType().FullName prüft.) Also in diesem Fall gibt es keinen großen Unterschied zwischen JsonConvert.DeserializeObject und JToken.Parse; entweder wird Ihnen das gleiche Ergebnis geben.

+0

Vielen Dank für die gut durchdachte Antwort! Die Object vs Dynamic Deskriptoren sind jetzt sinnvoll. Das Beispiel, das Sie geben, ist auch großartig - das sieht viel einfacher aus als mit JsonParseDynamic. – hubatish

+0

Kein Problem; froh, dass ich helfen konnte! –

+0

Ich wünschte, dies wäre in der [offiziellen Dokumentation] (http://www.newtonsoft.com/json/help/html/serializingjson.htm). –

11

JsonConvert.DeserializeObject hat einen Vorteil gegenüber JObject.Parse: Es ist möglich, benutzerdefinierte JsonSerializerSettings zu verwenden.

Dies kann sehr nützlich sein, z.B. wenn Sie steuern möchten, wie Datumsangaben deserialisiert werden. Standardmäßig werden Datumsangaben in DateTime-Objekten deserialisiert. Das bedeutet, dass Sie möglicherweise ein Datum mit einer anderen Zeitzone als die in der JSON-Zeichenfolge haben.

Sie können dieses Verhalten ändern, indem Sie ein JsonSerializerSetting und eine Einstellung DateParseHandling zu DateParseHandling.DateTimeOffset erstellen.

Ein Beispiel:

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" } 
Verwandte Themen