2017-09-25 9 views
0

사전을 serialize/deserialize하려고하는데 문제는 compareer가 StringComparer.OrdinalIgnoreCase 인 사전을 만드는 것입니다. 분명히StringComparer로 JSON 사전 deserialize

Different

:

var dict = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); 

dict["x"] = new Dictionary<string, string>(); 
dict["x"]["y"] = "something"; 

var serialized = JsonConvert.SerializeObject(dict); 

var unSerialized = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(serialized); 

Console.WriteLine((dict.Comparer == unSerialized.Comparer ? "Same" : "Different")); 

(.NET Fiddle - Try It)이 콘솔에 다음 밖으로

인쇄 : 여기

내가 겪고있어 문제의 코드입니다 JSON serializer는 사전을 만들 때 설정 한 Comparer를 직렬화하지 않지만 설정할 수 없다는 문제가 있습니다. Dictionary<TKey, TValue>.Comparer 이후의 사실 이후의 Comparer는 읽기 전용입니다.

나는 사용자 정의 JsonSerializerSetting과 관련이 있다고 확신하지만 컬렉션 생성을 차단하고 다른 비교자를 사용하여 사전을 반환하는 방법을 알아낼 수 없습니다.

당신이 새 사전의 생성자에 사용할 직렬화의 결과와 비교 자 모두 통과하면 당신은 당신의 사전의 생성자에 사용할 비교자를 지정할 수 있습니다
+0

확인을 Ron,이 json을 다른 사이트로 보냈다고 가정 해보십시오. 이 사전을 구성하는 방법을 어떻게 알 수 있습니까? (동일한 json을 만들기 위해 사전없이 다른 방법을 사용할 수도 있습니다.) –

+0

@ L.B이 응용 프로그램은 웹 기반이 아니며 XML을 통한 직렬화에 JSON을 사용하고 있습니다. 데이터는 외부 시스템에 의해 처리되지 않습니다. –

+0

이것은 논리를 설명하기위한 예일뿐입니다. json의 수신자는 어떻게 작성했는지 알지 못합니다. 그것은 당신이 그것을 만드는데 사용했던 언어조차 모른다. 그래서 잘못된 가정을한다. –

답변

2

당신은 할 수 있습니다 또한 PopulateObject와 기존 개체를 채우는 :

var dict = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); 

dict["x"] = new Dictionary<string, string>(); 
dict["x"]["y"] = "something"; 

var json = JsonConvert.SerializeObject(dict); 


var result = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); 
JsonConvert.PopulateObject(json, result); 

Console.WriteLine(result["x"]["y"]); 
Console.WriteLine(result.Comparer == dict.Comparer ? "Same" : "Diff"); 

출력 :

something 
Same 
+0

감사합니다.이 방법이 필요합니다. –

1

:

var unSerialized = 
    new Dictionary<string, Dictionary<string, string>> 
     (JsonConvert 
      .DeserializeObject<Dictionary<string, Dictionary<string, string>>>(serialized), 
      dict.Comparer); 
+0

고맙습니다. 고맙습니다. 사전의 생성자로 컬렉션을 반환하지 않았다고 생각합니다. –

2

아마도 조금 늦었 겠지만, JsonConverter을 사용하여 생성 된 JSON을 확장하는 것은 좀 더 복잡하지만 더 유연합니다. 내가 설명하는 경우에 대한 샘플을 만들었습니다, 그것은 완전하지 않다
.NET Fiddle - Try It
(당신이 그것을 사용하기로 결정한다면 연장 주시기) :

public class DictConverter<TValue> : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return true; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var obj = JToken.ReadFrom(reader);     
     if (objectType == typeof(Dictionary<string, TValue>)) 
     { 
      var comparer = obj.Value<string>("Comparer"); 
      Dictionary<string, TValue> result; 
      if (comparer == "OrdinalIgnoreCase") 
      { 
       result = new Dictionary<string, TValue>(StringComparer.OrdinalIgnoreCase); 
      } 
      else 
      { 
       result = new Dictionary<string, TValue>(); 
      } 
      obj["Comparer"].Parent.Remove(); 
      serializer.Populate(obj.CreateReader(), result); 
      return result; 
     } 
     return obj.ToObject(objectType); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var obj = JObject.FromObject(value); 
     if (value is Dictionary<string, TValue>) 
     { 
      if((value as Dictionary<string, TValue>).Comparer == StringComparer.OrdinalIgnoreCase) 
       obj.Add("Comparer", JToken.FromObject("OrdinalIgnoreCase")); 
     } 
     obj.WriteTo(writer); 

    } 
} 

및 사용

var dict = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); 

dict["x"] = new Dictionary<string, string>(); 
dict["x"]["y"] = "something"; 

var serialized = JsonConvert.SerializeObject(dict, 
    new DictConverter<Dictionary<string,string>>()); 
var unSerialized = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>> 
    (serialized, new DictConverter<Dictionary<string, string>>());