2013-05-31 1 views
2

Json.Net을 사용하여 System.Text.Encoding 유형의 속성을 가진 클래스를 serialize/deserialize하고 있습니다. 간단한 테스트를 시도, 내 수업은 문제없이 연재 :Json.Net을 사용하여 인코딩 값을 처리하는 더 좋은 방법이 있습니까?

이를 만들 수 없습니다 :

{ 
    "TheEncoding": { 
    "BodyName": "utf-8", 
    "EncodingName": "Unicode (UTF-8)", 
    "HeaderName": "utf-8", 
    "WebName": "utf-8", 
    "WindowsCodePage": 1200, 
    "IsBrowserDisplay": true, 
    "IsBrowserSave": true, 
    "IsMailNewsDisplay": true, 
    "IsMailNewsSave": true, 
    "IsSingleByte": false, 
    "EncoderFallback": { 
     "DefaultString": "?", 
     "MaxCharCount": 1 
    }, 
    "DecoderFallback": { 
     "DefaultString": "?", 
     "MaxCharCount": 1 
    }, 
    "IsReadOnly": true, 
    "CodePage": 65001 
    } 
} 

그러나, 직렬화 복원 때, 나는 예외를 가지고 :

public class TestClass { 
    public Encoding TheEncoding { get; set; } 
} 

var testClass = new TestClass { TheEncoding = Encoding.UTF8 }; 
var json = JsonConvert.SerializeObject(testClass, Formatting.Indented); 
var obj = JsonConvert.DeserializeObject<TestClass>(json); 

는에 직렬화 System.Text.Encoding 유형의 인스턴스 유형이 인 인터페이스 또는 추상 클래스이며 인스턴스화 할 수 없습니다. 경로 'TheEncoding.BodyName', 3 호선, 위치 (16)

내가 System.Text.Encoding 형식 처리하는 사용자 정의 변환기를 만들어이 문제를 과거를 얻을 수 있었다 :

public class JsonEncodingConverter : JsonConverter { 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { 
     // Serialize as the BodyName. 
     serializer.Serialize(writer, (value as Encoding).BodyName); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { 
     // Already good to go. 
     return existingValue; 
    } 

    public override bool CanConvert(Type objectType) { 
     return (typeof (Encoding).IsAssignableFrom(objectType)); 
    } 
} 

var testClass = new TestClass { TheEncoding = Encoding.UTF8 }; 
var json = JsonConvert.SerializeObject(testClass, Formatting.Indented, new JsonEncodingConverter()); 
var obj = JsonConvert.DeserializeObject<TestClass>(json , new JsonEncodingConverter()); 

{ 
    "TheEncoding": "utf-8" 
} 

을 그리고 사용자 정의 변환기 직렬화 복원 할 때이 JSON 성공적으로 라운드 트립 다시 원래의 객체가 될 수 있습니다 이제 사용자 정의 변환기 직렬화하는 생산하고 있습니다.

저는 Json.Net을 처음 접했고, 저는 이것이 어려운 길을 가고 있다는 강한 느낌을 가지고 있습니다! 확실히 System.Text.Encoding을 처리하는 방법이 더 좋고 덜 복잡합니다.

답변

2

[DataContract][DataMember] 속성을 사용하여 명시 적으로 어떤 속성이 TestClass 개체에 직렬화되도록 설정합니다.

  1. TheEncoding 속성의 [DataMember] 속성을 생략하십시오.
  2. "utf-8"(TheEncoding의 값에 따라)로 직렬화되는 도우미 속성을 만듭니다. 이 속성에 [DataMember] 특성을 포함하십시오.예를 들어

: TheEncoding 스킵되며 TheEncodingName 대신 직렬화 될 직렬화

[DataContract] 
public class TestClass 
{ 
    public Encoding TheEncoding { get; set; } 

    [DataMember] 
    public string TheEncodingName 
    { 
    get 
    { 
     if (this.TheEncoding == System.Text.Encoding.UTF8) 
     return "utf-8"; 
     // TODO: More possibilities 
    } 
    set 
    { 
     if (value == "utf-8") 
     this.TheEncoding = System.Text.Encoding.UTF8; 
     // TODO: More possibilities 
    } 
    } 
} 

.

+0

분명히 나는 ​​Json.Net을 처음 접하는 것이 아니라 일반적으로 .Net 직렬화에 익숙하다. 고마워, 그건 속임수 였어! – Darryl

0

이 문제에 접근하는 더 좋은 방법은 JSON 개체에서 필요한 속성을 정확하게 파악하는 것입니다.

서버 쪽 Encoding 개체의 모든 속성을 포함 할 이유는 .NET Framework의 일부로 런타임에 이미 액세스 할 수 있기 때문입니다.

클라이언트에서 Encoding 개체의 모든 속성이 필요한 이유가 무엇인지 상상할 수 없습니다.

EncodingName 또는 BodyName을 보내는 것이 더 직관적 일 수 있으며 서버에서 사용할 인코딩 개체를 결정할 수 있습니다.

예를 들어 utf-8을 지정하는 서버에 JSON을 보내려면 Encoding.UTF8을 사용해야합니다.

관련 문제