我正在使用Json.Net序列化/反序列化具有System.Text.Encoding类型属性的类。尝试一个简单的测试,我的班级序列化没有任何问题:
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 );
序列化为:
{
"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
}
}
然而,在反序列化时,我得到了一个例外:
无法创建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会有更好的,更少参与的方式吗?
答案 0 :(得分:2)
使用[DataContract]
和[DataMember]
属性明确设置将在TestClass
个对象上序列化哪些属性。
[DataMember]
媒体资源中的TheEncoding
属性。TheEncoding
的值)。在此媒体资源上添加[DataMember]
属性。例如:
[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
}
}
}
序列化后,系统会跳过TheEncoding
,而TheEncodingName
会被序列化。
答案 1 :(得分:0)
我认为解决这个问题的更好方法是弄清楚你在JSON对象上需要什么属性?
服务器端没有理由包含Encoding
对象中的所有属性,因为您已经在运行时作为.NET框架的一部分访问它。
在客户端上,我无法想象你为什么需要Encoding
对象的所有属性。
发送EncodingName
或BodyName
可能更直观,您可以从中确定要在服务器上使用的编码对象。
例如,如果我要向服务器发送一些指定utf-8
的JSON,我会知道使用Encoding.UTF8
。