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;
}
답변
LINQ-to-JSON API ( JObject
, JToken
등)는 구조를 미리 알 필요없이 JSON으로 작업 할 수 있도록 존재합니다. 를 사용하여 임의의 JSON을 역 직렬화 JToken.Parse
한 다음 다른 JToken
메서드를 사용하여 해당 콘텐츠를 검사하고 조작 할 수 있습니다 . LINQ-to-JSON은 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; }
}
Json.Net은 JsonConvert.DeserializeObject
생성 할 객체의 유형을 결정 하기 위해 메소드에 제공된 유형 인수 를 사용합니다.
당신이 호출 할 때 유형을 지정하지 않으면 물론, DeserializeObject
또는 사용 object
하거나 dynamic
, 다음 Json.Net는로 역 직렬화 할 수밖에 없다 JObject
. (확인을 통해 동적 변수가 실제로 a JObject
를 보유하고 있음을 직접 확인할 수 있습니다 jResults.GetType().FullName
.) 따라서이 경우 JsonConvert.DeserializeObject
와 사이에는 큰 차이가 없습니다 JToken.Parse
. 어느 쪽이든 동일한 결과를 제공합니다.
답변
JsonConvert.DeserializeObject는 JObject.Parse보다 한 가지 장점이 있습니다. 사용자 지정 JsonSerializerSettings를 사용할 수 있습니다.
이것은 날짜가 deserialize되는 방법을 제어하려는 경우에 매우 유용 할 수 있습니다. 기본적으로 날짜는 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" }
답변
JsonConvert.DeserializeObject가 Array / List json 텍스트를 직접 역 직렬화 할 수 있다는 이점을 알고 있었지만 JObject는 할 수 없습니다.
아래 샘플 코드를 시도하십시오.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace NetCoreJsonNETDemo
{
internal class Person
{
[JsonProperty]
internal string Name
{
get;
set;
}
[JsonProperty]
internal int? Age
{
get;
set;
}
}
internal class PersonContainer
{
public List<Person> Persons
{
get;
set;
}
}
class Program
{
static T RecoverPersonsWithJsonConvert<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json);
}
static T RecoverPersonsWithJObejct<T>(string json) where T : class
{
try
{
return JObject.Parse(json).ToObject<T>();
}
catch (Exception ex)
{
Console.WriteLine("JObject threw an Exception: " + ex.Message);
return null;
}
}
static void Main(string[] args)
{
List<Person> persons = new List<Person>();
persons.Add(new Person()
{
Name = "Jack",
Age = 18
});
persons.Add(new Person()
{
Name = "Sam",
Age = null
});
persons.Add(new Person()
{
Name = "Bob",
Age = 36
});
string json = JsonConvert.SerializeObject(persons, new JsonSerializerSettings()
{
Formatting = Formatting.Indented
});
List<Person> newPersons = RecoverPersonsWithJsonConvert<List<Person>>(json);
newPersons = RecoverPersonsWithJObejct<List<Person>>(json);//JObject will throw an error, since the json text is an array.
PersonContainer personContainer = new PersonContainer()
{
Persons = persons
};
json = JsonConvert.SerializeObject(personContainer, new JsonSerializerSettings()
{
Formatting = Formatting.Indented
});
newPersons = RecoverPersonsWithJObejct<PersonContainer>(json).Persons;
newPersons = null;
newPersons = RecoverPersonsWithJsonConvert<PersonContainer>(json).Persons;
Console.WriteLine("Press any key to end...");
Console.ReadKey();
}
}
}
답변
여기에 나와있는 사용법과 관련하여 제공되는 답변은 나에게 맞는 것입니다.-
Jobject.Parse
> Json이 강력하게 유형화되지 않았거나 Json의 구조를 미리 알지 못하는 경우
JsonConvert.DeserializeObject<T>
-> Json을 캐스팅 할 클래스 또는 유형을 알고있는 T
경우. 복합 클래스 또는 단순 유형일 수 있습니다 .
내 대답은 OP 코드에서와 같이 구조가 알려지지 않은 경우 성능을 기반으로 한 것입니다. 성능을 위해 두 방법의 사용을 벤치마킹하면 Jobject.Parse()
할당 된 메모리 측면에서 요금이 잘되는 것으로 관찰 되므로 이름을 무시하십시오. 메서드 중 먼저 ‘JsonConvert.DeserializeObject’로 메서드를 호출하고 두 번째 메서드는Jobject.Parse
답변
