有更好的方法来处理编码值与Json.Net



我正在序列化/反序列化一个类,它具有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吧?

使用[DataContract][DataMember]属性显式设置将在TestClass对象上序列化的属性。

  1. TheEncoding属性中省略[DataMember]属性。
  2. 创建一个被序列化为"utf-8"的helper属性(取决于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将被序列化。

我认为解决这个问题的更好方法是弄清楚JSON对象到底需要哪些属性?

服务器端没有理由包含Encoding对象的所有属性,因为作为。net框架的一部分,您已经可以在运行时访问它。

在客户端,我无法想象为什么需要Encoding对象的所有属性。

发送EncodingNameBodyName可能更直观,您可以从中确定在服务器上使用什么编码对象。

作为一个例子,如果我要发送一些JSON到服务器指定utf-8,我将知道使用Encoding.UTF8

相关内容

  • 没有找到相关文章

最新更新