JsonConvert.DeserializeObjectとJObject.Parseの違いは何ですか?私が知る限り、両方とも文字列を取り、Json.NETライブラリにあります。どちらの状況が他の状況よりも便利になるのでしょうか、それとも主に単なる好みですか?
参考までに、Json文字列を解析してJson属性の1つのリストを返すために、両方を使用してまったく同じことを行う例を次に示します。
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;
}
LINQ-to-JSON API(JObject
、JToken
など)は、事前に構造を知る必要なくJSONを操作できるようにするために存在します。 JToken.Parse
を使用して任意のJSONをデシリアライズし、他のJToken
メソッドを使用してその内容を調べて操作できます。 LINQ-to-JSONは、JSONから1つまたは2つの値(郡の名前など)だけが必要な場合にもうまく機能します。
一方、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; }
}
Json.NetはJsonConvert.DeserializeObject
メソッドに指定されたtype引数を使用して、作成するオブジェクトのタイプを決定することに注意してください。
もちろん、DeserializeObject
を呼び出すときにタイプを指定しない場合、またはobject
またはdynamic
を使用する場合、Json.Netにはデシリアライズする以外に選択肢はありませんJObject
。 (動的変数が実際にJObject
を保持していることは、jResults.GetType().FullName
を確認することで確認できます。)その場合、JsonConvert.DeserializeObject
とJToken.Parse
の間に大きな違いはありません。どちらでも同じ結果が得られます。
JsonConvert.DeserializeObjectには、JObject.Parseよりも1つの利点があります。カスタムの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" }