JSON序列化的对象数据类型 [英] Json serialization for Object Data Type

查看:178
本文介绍了JSON序列化的对象数据类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 公共类MyClass的
{
公共对象BidAutoObject {搞定;组; }
公共BOOL IsApplied {搞定;组; }
}



我有一个类像上面和我创建从JSON字符串上述Class对象。属性BidAutoObject的类型是对象的。对象可以是CxDays或AMPM。它是动态设置。我使用newtonsoft.JsonConvert.SerializeObject序列化的C#对象JSON字符串。 JSON序列化的outpout就像

 BidAutoObject:{
IsSun:真实,
IsMon:虚假,
IsTue:真实,
IsWed:真实,
IsThu:虚假,
IsFri:真实,
IsSat:真正的
}

所以我不能确定BidAutoObject类型是否是CxDays,或从上面的JSON字符串AMPM我怎么可以添加序列化过程中的类型信息。我是否需要添加任何属性为BidAutoObject?

 公共类CxDays 
{
公共BOOL IsSun {获取;集;}
公共BOOL IsMon {获取;集;}
公布尔IsTue {获取;设置;}
}

公共类AMPM
{
公共BOOL AM {获取;集;}
公共BOOL PM {获取;设置;}
公共BOOL MIX {获取;集;}
}

而不是BidAutoObject:在JSON字符串,我需要的类对象名称,如CxDays或JSON字符串AMPM。我们使用Jsonserializer设置。当我们设置TypeNameHandling = TypeNameHandling.Auto一个选项 - 这只会增加$ type属性实例在哪里声明的类型(即库)不匹配实例类型(即派生)。但它显示出class.Now我想显示仅适用于JSON字符串,而不是全名空间类名的完整的命名空间。


解决方案

如果你根本不希望出现在JSON出于某种原因(为什么?),你可以创建的 DefaultSerializationBinder ,然后设置它 JsonSerializerSettings.Binder

 公共类DefaultAssemblyBinder:DefaultSerializationBinder 
{
公共字符串DefaultAssemblyName {搞定;私人集; }
公共字符串DefaultNamespaceName {搞定;私人集; }

公共DefaultAssemblyBinder(字符串defaultAssemblyName,串defaultNamespaceName)
{
this.DefaultAssemblyName = defaultAssemblyName;
this.DefaultNamespaceName = defaultNamespaceName;
}

公众覆盖类型BindToType(字符串的AssemblyName,字符串的typeName)
{
如果(!string.IsNullOrEmpty(DefaultAssemblyName))
{
如果(string.IsNullOrEmpty(的AssemblyName))
的AssemblyName = DefaultAssemblyName;
}
如果
{
如果(的typeName = NULL&放!;&安培;!typeName.Contains())(string.IsNullOrEmpty(DefaultNamespaceName)!)
的typeName = DefaultNamespaceName +。 +的typeName;
}
返回base.BindToType(的AssemblyName,typeName的);
}

公共覆盖无效BindToName(类型serializedType,出字符串的AssemblyName,字符串出来的typeName)
{
base.BindToName(serializedType,出来的AssemblyName,出来的typeName) ;
如果(string.IsNullOrEmpty(DefaultAssemblyName)及!&安培;!=的AssemblyName NULL)
如果(的AssemblyName == DefaultAssemblyName)
的AssemblyName = NULL;
如果(string.IsNullOrEmpty(DefaultNamespaceName)及!&安培;!=的typeName NULL)
{
INT指数= typeName.LastIndexOf('。');
如果(指数℃下)
抛出新JsonSerializationException(的String.Format(类型{0}不以任何命名空间中,但默认命名空间{1}已定,serializedType.FullName ,DefaultNamespaceName));
如果(指数== DefaultNamespaceName.Length&放大器;&放大器;的String.Compare(DefaultNamespaceName,0的typeName,0指数,StringComparison.Ordinal)== 0)
的typeName = typeName.Substring(索引+ 1);
}
}
}



再后来:

  VAR测试=新MyClass的{IsApplied = TRUE,BidAutoObject =新CxDays {IsMon =假,IsSun = TRUE,IsTue = FALSE} }; 

VAR设置=新JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto,活页夹=新DefaultAssemblyBinder(typeof运算(MyClass的).Assembly.FullName的typeof(MyClass的).Namespace)};
VAR JSON = JsonConvert.SerializeObject(测试,Formatting.Indented,设置);
Console.WriteLine(JSON);



创建以下JSON:




  {
BidAutoObject:{
$类型:CxDays,
IsSun:真实,
IsMon:虚假,
IsTue:虚假
},
IsApplied:真正的
}




小提琴。



有关其他自定义粘结剂例如,看到的自定义文档 SerializationBinder


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

I have a class like above and I am creating the Json string from the above Class object. Property "BidAutoObject " is of type "object". The object may be "CxDays" or "AMPM". It is setting dynamically. I am using newtonsoft.JsonConvert.SerializeObject to serialize the C# object to Json string. The outpout of Json serialization is like

"BidAutoObject": {
    "IsSun": true,
    "IsMon": false,
    "IsTue": true,
    "IsWed": true,
    "IsThu": false,
    "IsFri": true,
    "IsSat": true
}

So I couldn't identify whether "BidAutoObject type is "CxDays" or "AMPM" from the above json string. how can I add the type information during the serialization process. Do I need to add any attribute to "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; }
}

Instead of ""BidAutoObject": in the Json string, I need the class object name such as "CxDays" or "AMPM" in the json string. We have one option using "Jsonserializer setting" .When we set TypeNameHandling = TypeNameHandling.Auto - this will add a $type property ONLY for instances where the declared type (i.e. Base) does not match the instance type (i.e. Derived). But it showing the full namespace of that class.Now I want to show only the class name in the Json string instead of full name space.

解决方案

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.

这篇关于JSON序列化的对象数据类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆