对象数据类型的Json序列化

时间:2016-01-03 11:36:41

标签: c# json serialization json.net

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
}

所以我无法确定" BidAutoObject类型是否是" CxDays"或者" AMPM"从上面的json字符串。如何在序列化过程中添加类型信息。我是否需要向" 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字符串中,我需要类对象名称,例如" CxDays"或者" AMPM"在json字符串中。我们有一个选项使用" Jsonserializer设置" 。当我们设置TypeNameHandling = TypeNameHandling.Auto时 - 这将仅为声明类型(即Base)与实例类型(即Derived)不匹配的实例添加$ type属性。但是它显示了该类的完整命名空间。现在我只想在Json字符串中显示类名而不是全名空间。

2 个答案:

答案 0 :(得分:1)

我想你要找的是TypeNameHandling中的JsonSerializerSettings,你需要添加它来进行去序列化。 只需将其设置为TypeNameHandling.Auto,它将为json添加一个类型属性,用于类型不等于声明类型的实例。

答案 1 :(得分:0)

如果您不希望程序集名称和命名空间名称出于某种原因出现在JSON中(为什么?),您可以创建自己的DefaultSerializationBinder自定义子类,然后将其设置为{ {3}}:

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
}

原型JsonSerializerSettings.Binder

有关其他自定义活页夹示例,请参阅文档中的fiddle