웹 서비스 호출에서 데이터를 다시 받고 있습니다. XML의 응답은 다음과 같습니다.
<a:Response>
<a:Witness>
<a:WitnessClass>
<a:Witness>
<a:SomeProperty>SomeValue</a:CITY>
<a:Other>whatever</a:Other>
</a:Witness>
</a:WitnessClass>
</a:Witness>
</a:Response>
Newtonsoft를 사용하여 객체를 직렬화하면 다음과 같이 표시됩니다 (객체를 데이터베이스에 Json 문자열로 저장합니다).
{
...other properties,
"Witness":
[
{"Witness":
{
"SomeProperty":"SomeValue",
"Other":"whatever"
}
}
]
}
json을 deserialize하고 싶은 POCO는 다음과 같습니다.
public class ResponseDto
{
public virtual List<Witness> Witnesses { get; set; }
}
이 메서드를 사용하면 Witnesses 목록이 null 인 것을 제외하고 다른 모든 항목이 문제없이 역 직렬화됩니다.
var dto = JsonConvert.DeserializeObject<ResponsetDto>(json);
다음을 수행하면이 작업을 수행 할 수 있습니다 (하지만이 작업을 수행하기 위해 수행 할 수있는 속성이나 다른 작업이 있는지 궁금합니다).
var dto = JsonConvert.DeserializeObject<ResponseDto>(json);
dto.Witnesses = new List<Witness>();
var o = JObject.Parse(json);
var token = o["Witness"];
foreach (var child in token.Children())
{
var innerWitness = child["Witness"];
var witness = innerWitness.ToObject<Witness>();
dto.Witnesses.Add(witness);
}
return dto;
편집하다
Newtonsoft 사이트의 문서를 살펴 보았지만 눈에 띄는 것은 보이지 않습니다. 변환기를 살펴 보았고 시도했지만 원하는 작업을 수행 할 수있는 예제가 없습니다.
추가 편집
다음을 수행하여 필요한 것을 얻을 수 있었지만 (Newtonsoft 사이트의 예를 기반으로),이 작업을 수행하는 더 좋고 / 쉬운 방법이 있는지 여전히 알고 싶습니다. 어떤 것):
[JsonExtensionData]
private IDictionary<string, JToken> _additionalData;
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
//Witness is odd due to the structure of the response (Witness has an array of Witness)
var o = _additionalData["Witness"];
if (o != null)
{
Witnesses = new List<Witness>();
foreach (var child in o.Children())
{
var innerWitness = child["Witness"];
var witness = innerWitness.ToObject<Witness>();
Witnesses.Add(witness);
}
}
}
public ResponseDto()
{
_additionalData = new Dictionary<string, JToken>();
}
이 JSON을 더 효율적으로 구문 분석하는 데 사용할 수있는 속성 또는 변환기 가 무엇을 의미하는지 잘 모르겠습니다 . 성능 문제가있는 경우 대안 조사를 시작하기 전에 프로파일 러 또는 기타 분석 도구를 사용하여 병목 현상이 발생한 위치를 경험적으로 확인 한다고 설명 하는 Eric Lippert 의이 기사 를 참조하십시오 .
즉, private IDictionary<string, JToken> _additionalData;
deserialization이 완료된 후 사전을 지우지 않아 지속적인 초과 메모리 사용 및 ResponseDto
나중에 다시 직렬화하는 데 문제가 발생할 수 있으므로 감시 목록을 임시로 캐시 하는 데 현재 사용하는 것이 이상적이지 않을 수 있습니다 .
대신 추가 수준의 중첩을 처리 ItemConverter
하기 위해 Witnesses
속성에를 적용 할 수 있습니다 .
public class ResponseDto
{
[JsonProperty("Witness", ItemConverterType=typeof(WitnessConverter))]
public virtual List<Witness> Witnesses { get; set; }
}
class WitnessConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException(string.Format("To avoid infinite recursion, {0} must be applied statically through attributes, not added at run time in serialization settings.", this));
}
class WitnessDto
{
[JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Serialize)]
public Witness Witness { get; set; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var dto = serializer.Deserialize<WitnessDto>(reader);
return dto.Witness;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, new WitnessDto { Witness = (Witness)value });
}
}
public class Witness
{
public string SomeProperty { get; set; }
public string Other { get; set; }
}
여기 에서는 JSON 성능 및 사용을 개선하는 11 가지 방법 기사에 제공된 권장 사항으로 인해 WitnessDto
로드 하는 대신 a JObject
를 사용했습니다 .
가능하다면 작업중인 JSON 구조와 일치하는 클래스가 있는지 확인하십시오. 일반 JSON을 JSON.net JObject 또는 FastJson을 사용하여 일반 사전으로 구문 분석하는 것은 해당 데이터를 정의 된 클래스 유형으로 읽는 것보다 느립니다 (~ 20 %). 일반 Json.NET의 JObject, JArray, JValue 객체를 사용하여 훨씬 더 많은 메타 데이터를 추적하기 때문일 수 있습니다.
그러나 확인하려면 자신을 프로파일 링해야합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다