JObject.Parse与JsonConvert.DeserializeObject

hub*_*ish 73 c# jsonserializer json.net

JsonConvert.DeserializeObject和JObject.Parse有什么区别?据我所知,两者都是一个字符串,并在Json.NET库中.什么样的情况会使一个人比另一个人更方便,还是主要只是偏好?

作为参考,这里有一个例子,我用两者做同样的事情 - 解析一个Json字符串并返回一个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;
}
Run Code Online (Sandbox Code Playgroud)

Bri*_*ers 76

存在LINQ-to-JSON API(JObject,JToken等)以允许使用JSON而无需提前知道其结构.您可以使用任何任意JSON反序列化JToken.Parse,然后使用其他JToken方法检查和操作其内容.如果您只需要JSON中的一个或两个值(例如县名),LINQ-to-JSON也可以正常工作.

JsonConvert.DeserializeObject另一方面,主要用于在提前了解JSON的结构并且想要反序列化为强类型类时使用.例如,以下是如何将JSON中的全部县数据集合到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; }
}
Run Code Online (Sandbox Code Playgroud)

请注意,Json.Net使用给予JsonConvert.DeserializeObject方法的type参数来确定要创建的对象类型.

当然,如果你在调用时没有指定类型DeserializeObject,或者你使用object或者dynamic,那么Json.Net别无选择,只能反序列化为JObject.(你可以自己看看你的动态变量实际上是JObject通过检查来保持的jResults.GetType().FullName.)所以在这种情况下,JsonConvert.DeserializeObject和之间没有太大区别JToken.Parse; 要么会给你相同的结果.

  • 我希望这是在[官方文档](http://www.newtonsoft.com/json/help/html/serializingjson.htm)中。 (2认同)

pbe*_*een 25

JsonConvert.DeserializeObject比JObject.Parse有一个优势:可以使用自定义JsonSerializerSettings.

这非常有用,例如,如果您想控制日期的反序列化方式.默认情况下,日期被反序列化为DateTime对象.这意味着您可能最终得到的日期与json字符串中的时区不同.

您可以通过创建JsonSerializerSetting并将DateParseHandling设置为DateParseHandling.DateTimeOffset来更改此行为.

一个例子:

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" }
Run Code Online (Sandbox Code Playgroud)