Json serialization for Object Data Type

前端 未结 2 1003
礼貌的吻别
礼貌的吻别 2020-12-20 08:02
public class MyClass
{ 
    public object BidAutoObject { get; set; }
    public bool IsApplied { get; set; }
}

I have a class like above and I am

相关标签:
2条回答
  • 2020-12-20 08:34

    I guess what you are looking for is the TypeNameHandling in the JsonSerializerSettings which you need to add for de- and serialization. Just set it to TypeNameHandling.Auto which will add a type property to the json for instances which have a type not equal to the declared type.

    0 讨论(0)
  • 2020-12-20 08:38

    If you simply don't want the assembly name and namespace name to appear in the JSON for some reason (why?), you can create your own custom subclass of DefaultSerializationBinder and then set it in 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);
            }
        }
    }
    

    And then, later:

            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);
    

    Creates the following JSON:

    {
      "BidAutoObject": {
        "$type": "CxDays",
        "IsSun": true,
        "IsMon": false,
        "IsTue": false
      },
      "IsApplied": true
    }
    

    Prototype fiddle.

    For another custom binder example, see Custom SerializationBinder from the documentation.

    0 讨论(0)
提交回复
热议问题