对象数据类型的 Json 序列化
本文关键字:序列化 Json 数据类型 对象 | 更新日期: 2023-09-27 18:28:57
public class MyClass
{
public object BidAutoObject { get; set; }
public bool IsApplied { get; set; }
}
我有一个像上面这样的类,我正在从上面的类对象创建 Json 字符串。属性"投标自动对象"的类型为"对象"。对象可能是"CxDays"或"AMPM"。它是动态设置的。我正在使用牛顿软件。JsonConvert.SerializeObject 将 C# 对象序列化为 Json 字符串。Json 序列化的输出就像
"BidAutoObject": {
"IsSun": true,
"IsMon": false,
"IsTue": true,
"IsWed": true,
"IsThu": false,
"IsFri": true,
"IsSat": true
}
所以我无法从上面的 json 字符串中确定"BidAutoObject 类型是"CxDays"还是"AMPM"。如何在序列化过程中添加类型信息。我需要向"投标自动对象"添加任何属性吗?
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"。我们有一个使用"Json序列化程序设置"的选项。当我们设置 TypeNameHandling = TypeNameHandling.Auto 时 - 这将添加一个 $type 属性,仅用于声明的类型(即 Base(与实例类型(即派生(不匹配的实例。但它显示了该类的完整命名空间。现在我只想在 Json 字符串中显示类名而不是全名空间。
我想您要查找的是JsonSerializerSettings
中需要添加以进行反序列化的TypeNameHandling
。只需将其设置为 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 }
原型小提琴。
有关另一个自定义绑定程序示例,请参阅文档中的自定义序列化绑定程序。