使用 Json.NET 代理 int、float 和 decimal

Posted

技术标签:

【中文标题】使用 Json.NET 代理 int、float 和 decimal【英文标题】:Surrogate int, float and decimal using Json.NET 【发布时间】:2015-05-14 14:21:11 【问题描述】:

我们使用 Json.net 进行序列化。我们希望几乎任何类型的用户定义的类/消息都可以序列化。

Json.net 无法立即支持的一件事是,如果您在 object 字段中存储 intfloatdecimal。 例如

 public class SomeMessage
 
      public object Something get;set;
 

如果我在Something字段中存储intfloatdecimal,它将被反序列化为longdouble(因为json.net只能猜测json 中基元的类型(“foo”:123

我完全知道我可以在属性上使用正确的类型并设置各种提示。

但我想为任何随机类/消息解决这个问题。

我目前的方法是自定义 JsonConverter,它处理上述类型,然后将它们序列化为代理类型,该类型将值作为字符串保存,并区分这是什么类型。 然后在 ReadJson 上,我将其转回正确的类型。

这样做有很多过热。 特别是对于代理类型的类型名。 "foo.bar.baz.PrimitiveSurrogate, mylib"

我可以自定义这个类型名的存储方式吗? 例如如果我想为某些特定类型应用别名?

还有其他方法吗? 我可以将整个内容序列化为一个特殊的字符串,它会更小,但话又说回来,感觉很不确定。

那么,如果我想在存储在无类型结构中时保持原语的正确类型,我有哪些选择?

[编辑]

普通Json:


    "foo":123

对比

我们当前的代理版本:


    "foo": 
                  "$type":"Akka.Serialization.PrimitiveSurrogate, Akka",
                  "V":"123",
                  "T":1
             

我可以只用 `"V":"123L" 替换 V 和 T 并解析后缀,因为我们只在该类型中存储 int、float 和 decimal,因此我们可以轻松获得硬编码的描述符。

但是,这仍然没有摆脱代理本身的 $type,我想至少将其缩短为类似 `"$type":"Surrogate" 或者那个方向的东西。

[再次编辑] 我把它归结为:

"$type":"Akka.Util.PrimitiveSurrogate, Akka","V":"F123.456"

但我真的很想摆脱长类型名并以某种方式替换为别名。

[再次编辑]

我现在明白了:

"$":"M123.456"

这已经足够好了。 我们不需要与任何其他 json 系统互操作,它只是我们两端的框架,所以即使它不漂亮,也可以使用。

【问题讨论】:

【参考方案1】:

有效载荷的大小有多重要?例如,您可以嵌入关于每个原语类型的元数据,本质上是将数据合同与数据捆绑在一起。例如:


    "someInteger": 123,
    "$someInteger.clrType": " System.Int32"

编辑:

如果负载大小最重要,您可以执行以下操作:


  "someInteger.i": 123

这会将有效负载增加到每个原始值两个字符。我很确定这个点可以安全地用作分隔符;即 CLR 标识符不应该具有标识符“someInteger.i”,尽管我会根据规范仔细检查这一点(CLR 中允许的标识符字符由以下文档管理,附件 7 http://www.unicode.org/reports/tr15/tr15-18.html#Programming%20Language%20Identifiers) .

如果您真的想压缩它,您可以删除分隔符 (.) 并在属性名称后加上一个 CLR 规范不允许的 Unicode 字符,以表示所需的原始类型。有点hacky,但它会减少另一个字节的有效负载。 ;-)

【讨论】:

我意识到这与您当前的方法非常相似,但如果我正确解释了您的问题,我看不出有任何解决方法。类型信息必须放在某个地方,如果您不想提示类型本身,那么除了序列化的有效负载本身之外还有什么地方? 是的,看看我的编辑,我已经添加了我们当前代理方法的输出。 首要任务是什么?有效载荷大小?便携性/兼容性?性能? 有效负载大小,也许可以通过使用 JObject 手动处理 json 并对其进行一些自定义检查来实现。 在这种情况下,我认为将类型信息嵌入到 JSON 键中可能是这样做的方法(请参阅我的上次编辑)。这样,您可以跳过值周围的引号,仅使用 1 或 2 个字符来表示类型。不是很便携,但可能是最紧凑的 JSON 解决方案。

以上是关于使用 Json.NET 代理 int、float 和 decimal的主要内容,如果未能解决你的问题,请参考以下文章

使用字符串、int 数组反序列化 json - .net core C#

python怎么float转成int

javascript 怎么将float强制转换为int类型

使用按位运算将 Int 转换为 Float 或将 Float 转换为 Int(软件浮点)

java, int如何转float,??

int,float数据类型转string