对象数据类型的Json序列化

public class MyClass { public object BidAutoObject { get; set; } public bool IsApplied { get; set; } } 

我有一个类似上面的类,我正在从上面的Class对象创建Json字符串。 属性“BidAutoObject”的类型为“object”。 对象可以是“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设置“。当我们设置TypeNameHandling = TypeNameHandling.Auto时 – 这将仅为声明类型(即Base)与实例类型(即Derived)不匹配的实例添加$ type属性。但它显示该类的完整命名空间。现在我只想显示类名Json字符串而不是全名空间。

我想你要找的是JsonSerializerSettingsTypeNameHandling ,你需要为de-和serialization添加它。 只需将其设置为TypeNameHandling.Auto ,它将为json添加一个类型属性,用于类型不等于声明类型的实例。

如果您不希望程序集名称和命名空间名称出于某种原因出现在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 } 

原型小提琴 。

有关另一个自定义绑定器示例,请参阅文档中的Custom SerializationBinder 。