对象数据类型的 Json 序列化
Posted
技术标签:
【中文标题】对象数据类型的 Json 序列化【英文标题】:Json serialization for Object Data Type 【发布时间】:2016-04-07 04:13:26 【问题描述】:public class MyClass
public object BidAutoObject get; set;
public bool IsApplied get; set;
我有一个像上面这样的类,我正在从上面的 Class 对象创建 Json 字符串。属性“BidAutoObject”属于“对象”类型。该对象可能是“CxDays”或“AMPM”。它是动态设置的。我正在使用 newtonsoft.JsonConvert.SerializeObject 将 C# 对象序列化为 Json 字符串。 Json 序列化的输出是这样的
"BidAutoObject":
"IsSun": true,
"IsMon": false,
"IsTue": true,
"IsWed": true,
"IsThu": false,
"IsFri": true,
"IsSat": true
所以我无法从上面的json字符串中识别“BidAutoObject类型是“CxDays”还是“AMPM”。如何在序列化过程中添加类型信息。是否需要在“BidAutoObject”中添加任何属性?
public class CxDays
public bool IsSun get; set;
public bool IsMon get; set;
public bool IsTue get; set;
public class AMPM
public bool AM get; set;
public bool PM get; set;
public bool MIX get; set;
而不是 ""BidAutoObject": 在 Json 字符串中,我需要 json 字符串中的类对象名称,例如 "CxDays" 或 "AMPM"。我们有一个使用 "Jsonserializer setting" 的选项。当我们设置 TypeNameHandling = TypeNameHandling.Auto - 这将只为声明类型(即 Base)与实例类型(即 Derived)不匹配的实例添加 $type 属性。但它显示了该类的完整命名空间。现在我只想显示Json 字符串中的类名而不是全名空间。
【问题讨论】:
这看起来确实像 XY 问题。你想做什么? 如果您作为开发人员无法识别它是哪个具体对象,您如何期望 JSON.NET 等框架能够识别它? 但它显示了该类的完整命名空间——那么问题是什么?根据您的描述,听起来 Json.NET 正在成功地序列化和反序列化类型信息。 我已经更新了问题 【参考方案1】:我猜你正在寻找的是JsonSerializerSettings
中的TypeNameHandling
,你需要添加它以进行反序列化和序列化。
只需将其设置为TypeNameHandling.Auto
,这将为类型不等于声明类型的实例添加一个类型属性到 json。
【讨论】:
【参考方案2】:如果出于某种原因(为什么?)您只是不希望程序集名称和命名空间名称出现在 JSON 中,您可以创建自己的 DefaultSerializationBinder
的自定义子类,然后将其设置在 JsonSerializerSettings.Binder
中:
public class DefaultAssemblyBinder : DefaultSerializationBinder
public string DefaultAssemblyName get; private set;
public string DefaultNamespaceName get; private set;
public DefaultAssemblyBinder(string defaultAssemblyName, string defaultNamespaceName)
this.DefaultAssemblyName = defaultAssemblyName;
this.DefaultNamespaceName = defaultNamespaceName;
public override Type BindToType(string assemblyName, string typeName)
if (!string.IsNullOrEmpty(DefaultAssemblyName))
if (string.IsNullOrEmpty(assemblyName))
assemblyName = DefaultAssemblyName;
if (!string.IsNullOrEmpty(DefaultNamespaceName))
if (typeName != null && !typeName.Contains("."))
typeName = DefaultNamespaceName + "." + typeName;
return base.BindToType(assemblyName, typeName);
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
base.BindToName(serializedType, out assemblyName, out typeName);
if (!string.IsNullOrEmpty(DefaultAssemblyName) && assemblyName != null)
if (assemblyName == DefaultAssemblyName)
assemblyName = null;
if (!string.IsNullOrEmpty(DefaultNamespaceName) && typeName != null)
int index = typeName.LastIndexOf('.');
if (index < 0)
throw new JsonSerializationException(string.Format("Type 0 does not exist in any namespace, but a default namespace 1 has been set", serializedType.FullName, DefaultNamespaceName));
if (index == DefaultNamespaceName.Length && string.Compare(DefaultNamespaceName, 0, typeName, 0, index, StringComparison.Ordinal) == 0)
typeName = typeName.Substring(index + 1);
然后,稍后:
var test = new MyClass IsApplied = true, BidAutoObject = new CxDays IsMon = false, IsSun = true, IsTue = false ;
var settings = new JsonSerializerSettings TypeNameHandling = TypeNameHandling.Auto, Binder = new DefaultAssemblyBinder(typeof(MyClass).Assembly.FullName, typeof(MyClass).Namespace) ;
var json = JsonConvert.SerializeObject(test, Formatting.Indented, settings);
Console.WriteLine(json);
创建以下 JSON:
"BidAutoObject": "$type": "CxDays", "IsSun": true, "IsMon": false, "IsTue": false , "IsApplied": true
原型fiddle。
有关另一个自定义活页夹示例,请参阅文档中的 Custom SerializationBinder。
【讨论】:
以上是关于对象数据类型的 Json 序列化的主要内容,如果未能解决你的问题,请参考以下文章