在创建JsonObjectContract时禁止$ type

布兰农

我试图在Json.NET中强制抑制一些特定的$ type输出(同时保留其他输出)。它们在我的应用程序中是不必要的。Json.NET源代码显示了这一点:

private bool ShouldWriteType(...)
{
  TypeNameHandling resolvedTypeNameHandling =
    ((member != null) ? member.TypeNameHandling : null)
    ?? ((containerProperty != null) ? containerProperty.ItemTypeNameHandling : null)
    ?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null)
    ?? Serializer._typeNameHandling;

这让我认为我可以通过ItemTypeNameHandling在容器协定中设置来覆盖序列化程序设置las,它不适用于数组。我尝试重写该方法以获取数组协定,但是那里的设置会影响数组中的每个项目。那不是我想要的 (然后SignalR在对象数组中发送所有方法参数。)这是我的完整演示代码,在这里我试图弄清楚如何A在输出中保留类型,但抑制B(和所有sealed类)的类型如何覆盖合同解析器以正确执行此操作?

using System;
using System.Diagnostics;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace DemoBadTypeInclusion
{
    class A { public int P1 { get; set; } }

    // this attribute doesn't work and I don't want to have to reference Json.NET in my POCO
    //[JsonObject(ItemTypeNameHandling = TypeNameHandling.None)]
    sealed class B { public int P2 { get; set; } }

    internal class DtoContractResolver : DefaultContractResolver
    {
        protected override JsonObjectContract CreateObjectContract(Type objectType)
        {
            var contract = base.CreateObjectContract(objectType);
            if (objectType.IsSealed && objectType.BaseType == typeof(object))
            {
                contract.ItemTypeNameHandling = TypeNameHandling.None;
            }
            return contract;
        }
    }

    class Program
    {
        static void Main()
        {
            var objs = new object[] {new A {P1 = 3}, new B {P2 = 4}};

            var settings = new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.Auto,
                NullValueHandling = NullValueHandling.Ignore,
                TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple,
                ContractResolver = new DtoContractResolver(),
            };

            var json = JsonConvert.SerializeObject(objs, settings);
            Console.WriteLine(json);

            if (Debugger.IsAttached)
                Console.ReadKey();
        }
    }
}

更新:在进一步研究了Json.NET代码之后,看来这一行SerializeList是我麻烦的根源:

JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);

我需要后备值(GetContractSafe)。有人知道如何使FinalItemContractnull吗?

安德里亚斯·迪恩伯格(Andreas Dirnberger)

如果取消对对象Array的一种类型引用,则将使Array不可反序列化。因此,您可以取消对Array的所有类型引用。

仅抑制对象数组的类型引用

protected override JsonArrayContract CreateArrayContract(Type objectType)
{
            var c = base.CreateArrayContract(objectType);

            if(objectType == typeof(Object[]))
                c.ItemTypeNameHandling = TypeNameHandling.None;

            return c;
}

如果您不需要反序列化回到原始对象,只需设置

new JsonSerializerSettings
{
  TypeNameHandling = TypeNameHandling.None,
  ...
};

我知道这不是一个确切的答案,但是我看不到使用组件来标识对象数组中具有反序列化类型的某些元素的情况。所以我认为,这就是为什么json.net不支持它的原因

毕竟,这里是一种变通方法,它仅抑制一种类型:

static void Main()
        {
            var objs = new object[] { new A { P1 = 3 }, new B { P2 = 4 } };

            var settings = new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.Objects,
                NullValueHandling = NullValueHandling.Ignore,
                TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple,
                ContractResolver = new DtoContractResolver(),
            };


            var serial = JsonSerializer.Create(settings);

            var jsonArray = new JArray();


            foreach (var obj in objs)
            {
                if (obj != null && obj.GetType().IsSealed && obj.GetType().BaseType == typeof(object))
                    serial.TypeNameHandling = TypeNameHandling.None;
                else
                    serial.TypeNameHandling = TypeNameHandling.Objects;

                jsonArray.Add(JObject.FromObject(obj, serial));
            }

            var json = jsonArray.ToString(Formatting.None);
            Console.WriteLine(json);

            if (Debugger.IsAttached)
                Console.ReadKey();
        }

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在创建JsonObjectContract时禁止$ type

来自分类Dev

Powershell Add-Type在编译.dll(C#)时禁止创建.pdb

来自分类Dev

创建套接字时禁止sslpeerunverifiedexception

来自分类Dev

尝试创建mnesia表时出现“ bad_type”错误

来自分类Dev

在Type脚本中创建Dictionary时使用常量作为键

来自分类Dev

如何从Observable <List <Type >>创建Observable <Type>

来自分类Dev

从PropertyInfo创建通用列表<Type>

来自分类Dev

从PropertyInfo创建通用列表<Type>

来自分类Dev

使用 3 参数创建 TYPE

来自分类Dev

创建IAM角色时出错:MalformedPolicyDocument:禁止了字段Resource

来自分类Dev

使用fs writeFile创建文件时,nodeJS返回Type Error

来自分类Dev

React.createElement:type不能为null,未定义。.创建/渲染组件时

来自分类Dev

用`type`动态创建Django模型

来自分类Dev

从Lambda中的多个实体创建单个Type

来自分类Dev

从System.Type在AppDomain中创建实例

来自分类Dev

#type输入空白时,VBA功能出错

来自分类Dev

模式匹配时Scala Seq [Type]错误

来自分类Dev

什么是解析时 Option Type 的实例?

来自分类Dev

使用“ __”时禁止加粗

来自分类Dev

为<input type =“ week” />创建EditorFor时,我的models属性应该使用哪种数据类型?

来自分类Dev

当我尝试使用 super(type, obj) 创建绑定类方法时,有一些不同的东西

来自分类Dev

使用“创建...如果不存在”时禁止显示“通知:关系存在”

来自分类Dev

使用Scapy创建空的pcap文件时出现Python禁止警告

来自分类Dev

Rails 4:与指定属性关联的父对象已经存在时,禁止创建父对象

来自分类Dev

'基地被禁止。需要用户。” 尝试创建QBCustomObject时发生错误

来自分类Dev

使用Python Eve创建资源时,如何在请求中禁止“ _id”?

来自分类Dev

创建IAM角色时出错。MalformedPolicyDocument:具有禁止字段Resource。地貌

来自分类Dev

尝试从主题创建索引时,Elasticsearch Sink连接器抛出403禁止的异常

来自分类Dev

创建MultiUserChat时出现“ $ XMPPErrorException:XMPPError:禁止-身份验证”错误

Related 相关文章

  1. 1

    在创建JsonObjectContract时禁止$ type

  2. 2

    Powershell Add-Type在编译.dll(C#)时禁止创建.pdb

  3. 3

    创建套接字时禁止sslpeerunverifiedexception

  4. 4

    尝试创建mnesia表时出现“ bad_type”错误

  5. 5

    在Type脚本中创建Dictionary时使用常量作为键

  6. 6

    如何从Observable <List <Type >>创建Observable <Type>

  7. 7

    从PropertyInfo创建通用列表<Type>

  8. 8

    从PropertyInfo创建通用列表<Type>

  9. 9

    使用 3 参数创建 TYPE

  10. 10

    创建IAM角色时出错:MalformedPolicyDocument:禁止了字段Resource

  11. 11

    使用fs writeFile创建文件时,nodeJS返回Type Error

  12. 12

    React.createElement:type不能为null,未定义。.创建/渲染组件时

  13. 13

    用`type`动态创建Django模型

  14. 14

    从Lambda中的多个实体创建单个Type

  15. 15

    从System.Type在AppDomain中创建实例

  16. 16

    #type输入空白时,VBA功能出错

  17. 17

    模式匹配时Scala Seq [Type]错误

  18. 18

    什么是解析时 Option Type 的实例?

  19. 19

    使用“ __”时禁止加粗

  20. 20

    为<input type =“ week” />创建EditorFor时,我的models属性应该使用哪种数据类型?

  21. 21

    当我尝试使用 super(type, obj) 创建绑定类方法时,有一些不同的东西

  22. 22

    使用“创建...如果不存在”时禁止显示“通知:关系存在”

  23. 23

    使用Scapy创建空的pcap文件时出现Python禁止警告

  24. 24

    Rails 4:与指定属性关联的父对象已经存在时,禁止创建父对象

  25. 25

    '基地被禁止。需要用户。” 尝试创建QBCustomObject时发生错误

  26. 26

    使用Python Eve创建资源时,如何在请求中禁止“ _id”?

  27. 27

    创建IAM角色时出错。MalformedPolicyDocument:具有禁止字段Resource。地貌

  28. 28

    尝试从主题创建索引时,Elasticsearch Sink连接器抛出403禁止的异常

  29. 29

    创建MultiUserChat时出现“ $ XMPPErrorException:XMPPError:禁止-身份验证”错误

热门标签

归档