【问题标题】:How to serialize external classes into json with custom field names in Json.Net?如何在 Json.Net 中使用自定义字段名称将外部类序列化为 json?
【发布时间】:2014-02-19 19:21:58
【问题描述】:

我有一个无法修改的外部数据合同。 Json 用于序列化这些类。我需要节省输出数据的大小,所以我想将原始字段名称更改为更短的版本,即:

public ClassWithLongName
{
    public string FieldWithLongName = "field1";
    public string FieldWithEvenLongerName = "field2";
} 

应该被序列化为:

{"f1" = "field1", "f2" = "field2"}

为了能够正确反序列化它,必须以某种方式提供原始名称和短名称之间的映射(我在考虑 dictionary. 我应该为此使用 CustomConverter 还是 IContractResolver?

编辑:

有一种方法可以使用 CustomContractResolver:DefaultContractResolver。我正在重写 CreateProperty 方法来交换属性名称。问题是我无法获得序列化的对象类型(因此所有属性的名称都保存在一个公共映射中,而不是每种类型的单独映射)。你知道如何从 DefaultContractResolver 获取序列化的对象类型吗?

EDIT2:

类型可以取自 ResolveContract 方法(这里作为参数传递)。我已经实现了我需要的功能,但它存在一个巨大的问题。表现。我计算了循环序列化简单对象 10000 次所用的时间。默认序列化约为 150 毫秒,自定义序列化约为 15 秒。 你知道有没有办法避免它。我想开销是由反射引起的。但是默认序列化程序如何避免它呢?我使用 DefaultContractResolver 作为我的 CustomContractResolver 的父类,所以它应该使用父类正在使用的所有机制..

【问题讨论】:

    标签: c# .net json json.net


    【解决方案1】:

    使用匿名对象:

    ClassWithLongName obj = new ClassWithLongName();
    var anonymouse  =  new { FieldWithLongName = obj.FieldWithEvenLongerName, FieldWithEvenLongerName = obj.FieldWithEvenLongerName };
    
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    var output = serializer.Serialize(anonymouse);
    

    【讨论】:

    • 我将如何反序列化对象?反序列化器如何知道 json 中的哪个字段对应于 c# 对象中的哪个字段?
    • JsonConvert.DeserializeObject(myjsondata);
    • 第一个问题应该是:输出是什么样的(以及如何自定义)?
    【解决方案2】:

    如果您不想使用匿名对象,您可以创建自己的对象并使用AutoMapper 将外部数据协定映射到您自己的类中,然后使用JavaScriptSerializer 类对其进行序列化

    【讨论】:

    • 如标题所述,我想使用Json.Net库。此外,目前复制对象(如 Automapper 所做的那样)不是一种选择。我要求在该特定库(Newtonsoft Json.Net)中自定义序列化(和反序列化)的可能性。
    • 如果不能访问类,您将无法自定义输出。您要么需要映射到自己的类并序列化,要么创建一个匿名对象并对其进行序列化
    • 我认为有一个简单的解决方案。我可以使用装饰器模式来装饰带有 json 属性的原始属性。
    猜你喜欢
    • 2022-11-15
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 2013-12-29
    • 2023-03-03
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多