使用 json.net 对对象属性进行条件序列化/反序列化[重复]

2023-12-27

我有一个场景,其类定义如下:

class MyObject
{
    public DataDictionary MyObjectData { get; set; }

    public bool ShouldSerializeMyObjectData() { return true; }
    public bool ShouldDeserializeMyObjectData() { return false; }
}

当我尝试使用 JSON.net 序列化/反序列化该类时,它需要应该序列化 http://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_Serialization_JsonProperty_ShouldSerialize.htm考虑在内,但不考虑应该反序列化 http://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_Serialization_JsonProperty_ShouldDeserialize.htm.

根据文档,我猜两者的工作方式应该相同。有什么特别的事情我应该知道吗?更一般地说,我应该如何处理想要序列化属性但不反序列化它的场景?

我在用着Json.NET 8.0如果这很重要的话。

感谢您的帮助。


你的问题的简短回答是,自动检查ShouldDeserialize{PropertyName}()目前尚未实施,尽管ShouldSerialize{PropertyName}() is.接下来是更长的答案和解决方法。

班上JsonProperty http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_JsonProperty.htm由 Json.NET 在内部使用来定义如何将 JSON 属性映射到 .NET 成员或构造函数参数的协定。它有两个谓词属性,ShouldSerialize http://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_Serialization_JsonProperty_ShouldSerialize.htm and ShouldDeserialize http://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_Serialization_JsonProperty_ShouldDeserialize.htm当非空时,分别阻止属性被序列化和反序列化。初始化每个JsonProperty是的工作ContractResolver http://www.newtonsoft.com/json/help/html/ContractResolver.htm。对于每个属性{PropertyName}, Json.NET 的默认合约解析器 http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_DefaultContractResolver.htm自动检查是否存在public bool ShouldSerialize{PropertyName}() https://msdn.microsoft.com/en-us/library/53b8022e%28v=vs.110%29.aspx方法。如果存在这样的方法,它会在ShouldSerialize谓词,从而在方法返回时抑制序列化false。这是因为通过方法控制属性序列化而实现的ShouldSerialize{PropertyName}()是一个标准模式,例如,XmlSerializer https://stackoverflow.com/questions/5818513/xml-serialization-hide-null-values。有关更多背景信息,请参阅相关内容Json.NET 发行说明 http://james.newtonking.com/archive/2010/04/16/json-net-3-5-release-7-bson-binary-json-part-deux.

例如,在下面的类中,序列化MyObjectData将被压制,除非MyObjectData.Count > 0:

class MyObject
{
    public DataDictionary MyObjectData { get; set; }

    public bool ShouldSerializeMyObjectData() { return MyObjectData != null && MyObjectData.Count > 0; }
}

JsonProperty.ShouldDeserialize, 然而,默认合约解析器永远不会设置它。这可能是因为没有相当于反序列化的标准模式ShouldSerialize{PropertyName}()因此 Newtonsoft 从未收到任何实施此类模式的请求。然而,正如您所注意到的,支持这种模式的基础设施是存在的,因此应用程序可以创建自定义合约解析器 http://www.newtonsoft.com/json/help/html/CustomContractResolver.htm就是这样做的。事实上,Json.NET 自己有一个这样的契约解析器的例子测试套件 https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json.Tests/Serialization/ShouldSerializeTests.cs:

public class ShouldDeserializeContractResolver : DefaultContractResolver
{
    public static new readonly ShouldDeserializeContractResolver Instance = new ShouldDeserializeContractResolver();

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        MethodInfo shouldDeserializeMethodInfo = member.DeclaringType.GetMethod("ShouldDeserialize" + member.Name);

        if (shouldDeserializeMethodInfo != null)
        {
            property.ShouldDeserialize = o => { return (bool)shouldDeserializeMethodInfo.Invoke(o, null); };
        }

        return property;
    }
}

public class ShouldDeserializeTestClass
{
    [JsonExtensionData]
    public IDictionary<string, JToken> ExtensionData { get; set; }

    public bool HasName { get; set; }
    public string Name { get; set; }

    public bool ShouldDeserializeName()
    {
        return HasName;
    }
}

如果您想有条件地抑制属性的反序列化,即使属性存在于 JSON 中,您也可以使用此契约解析器。

Notes:

  • 如果您确实使用自定义合同解析器,您应该缓存并重用它 https://www.newtonsoft.com/json/help/html/Performance.htm#ReuseContractResolver以获得最佳性能。

  • JsonProperty.ShouldDeserialize在反序列化属性值之前调用。如果返回 true,则跳过该属性,无法检查该属性的内容。因此它不能用于基于该值实现自定义过滤。

  • JSON 对象的定义是JSON标准 https://www.json.org/json-en.html as an 无序的一组名称/值对。因此一个ShouldDeserialize假设其他属性已被读入的方法可能是brittle https://en.wikipedia.org/wiki/Software_brittleness.

    相反,如果您想根据另一个属性的值跳过一个属性的反序列化,请考虑使用[OnDeserialized] https://www.newtonsoft.com/json/help/html/SerializationCallbacks.htm反序列化所有属性后,回调并清除不需要的值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 json.net 对对象属性进行条件序列化/反序列化[重复] 的相关文章

  • 用于代数简化和求解的 C# 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 网络上有很多代数求解器和简化器 例如 algebra com 上不错的代数求解器和简化器 然而 我正在
  • 每个托管线程是否都有自己对应的本机线程?

    我想知道是否在 Net 中创建托管线程 通过调用Thread Start 导致在后台创建一个本机线程 那么托管线程是否有对应的本机线程呢 如果是 当托管线程等待或睡眠时 是否意味着相应的本机线程也在等待或睡眠 是的 NET 线程映射到所有当
  • 使用 std::packaged_task/std::exception_ptr 时,线程清理程序报告数据争用

    我遇到了线程清理程序 TSan 的一些问题 抱怨某些生产代码中的数据争用 其中 std packaged task 通过将它们包装在 std function 中而移交给调度程序线程 对于这个问题 我简化了它在生产中的作用 同时触发 TSa
  • 注销租约抛出 InvalidOperationException

    我有一个使用插件的应用程序 我在另一个应用程序域中加载插件 我使用 RemoteHandle 类http www pocketsilicon com post Things That Make My Life Hell Part 1 App
  • 错误:表达式不产生值

    我尝试将以下 C 代码转换为 VB NET 但在编译代码时出现 表达式不产生值 错误 C Code return Fluently Configure Mappings m gt m FluentMappings AddFromAssemb
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • 单个对象的 Monogame XNA 变换矩阵?

    我读过一些解释 XNA Monogame 变换矩阵的教程 问题是这些矩阵应用于 SpriteBatch Begin matrix 这意味着所有 Draw 代码都将被转换 如何将变换矩阵应用于单个可绘制对象 就我而言 我想转换滚动背景 使其自
  • 获取两个工作日之间的天数差异

    这听起来很简单 但我不明白其中的意义 那么获取两次之间的天数的最简单方法是什么DayOfWeeks当第一个是起点时 如果下一个工作日较早 则应考虑在下周 The DayOfWeek 枚举 http 20 20 5B1 5D 3a 20htt
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 如何在 Xaml 文本中添加电子邮件链接?

    我在 Windows Phone 8 应用程序中有一些大文本 我希望其中有电子邮件链接 例如 mailto 功能 这是代码的一部分
  • C#:帮助理解 UML 类图中的 <>

    我目前正在做一个项目 我们必须从 UML 图编写代码 我了解 UML 类图的剖析 但我无法理解什么 lt
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • Cmake 链接共享库:包含库中的头文件时“没有这样的文件或目录”

    我正在学习使用 CMake 构建库 构建库的代码结构如下 include Test hpp ITest hpp interface src Test cpp ITest cpp 在 CMakeLists txt 中 我用来构建库的句子是 f
  • 使用 C# 读取 Soap 消息

  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • 我的班级应该订阅自己的公共活动吗?

    我正在使用 C 3 0 遵循标准事件模式我有 public event EventHandler

随机推荐

  • 如何在 Mac 上卸载 Composer?

    我已经安装了Composer https getcomposer org用这个命令 php r copy https getcomposer org installer composer setup php php r if hash fi
  • Android 2.1:单个 Activity 中的多个处理程序

    我有不止一个Handlers在活动中 我在中创建所有处理程序onCreate 的主要活动 我的理解是handleMessage 每个处理程序的方法永远不会同时被调用 因为所有消息都放在同一个队列 Activity 线程 MessageQue
  • Azure 持久功能和数据保留

    我可以看到 azure 持久函数使用存储帐户来管理状态和检测 当在具有大量数据的环境中运行持久函数时 表和队列会变得越来越大 并且速度会越来越慢 持久功能清洁是否会自行记录它们 或者这是您需要自己完成的任务吗 经过研究后 开发人员似乎需要为
  • Mongoid分页

    I tried posts Post page params page per page 10 and posts Post paginate page gt 1 per page gt 10 但这两种方法都行不通 undefined me
  • 如何在模板助手中使用 Meteor 方法

    如何定义一个可以在模板助手中调用的 Meteor 方法 我有这两个文件 文件 lib test js Meteor methods viewTest function str return str 文件 客户端 myView js Temp
  • 未找到代理 JAR 或没有代理类属性

    已修复 这不是代码导致的错误 这是因为 IDE 我只是尝试为一款名为 Minecraft 的游戏进行注入 但我有一个问题 无法加载代理 这是例外情况 Exception in thread main com sun tools attach
  • 检测父进程何时退出

    我将有一个用于处理网络服务器重新启动的父进程 它将向子级发出信号以停止侦听新请求 子级将向父级发出信号以表明其已停止侦听 然后父级将向新子级发出信号以表明其可以开始侦听 通过这种方式 我们可以实现该级别重新启动的停机时间少于 100 毫秒
  • 文件夹中的新文件事件

    有人可以帮助我了解如何构建一个 24 7 运行的软件来侦听特定文件夹 例如 C Actions 并且每次我在该文件夹中放置一个新文件时 该软件都需要读取和处理它 如果文件夹中没有文件 软件不应只等待下一个文件的到来而什么也不做 文件 act
  • ASP.NET 动态控件计数(随时创建控件)

    我正在尝试创建一个复合 ASP NET 控件 让您可以构建可编辑的控件集合 我的问题是 当我按下添加或回发按钮 除了回发表单之外什么也不做 时 在文本框中输入的任何值都会丢失 当控件数量在回发之间发生变化时 我无法让它工作 我基本上需要能够
  • 理论计算机科学主题是否具有“现实世界”的开发应用?

    我所说的 理论计算机科学主题 指的是常规语言与非常规语言 泵引理和语法等内容 我熟悉有限自动机和正则表达式的现实世界应用 但诸如此类的其他主题给我带来了更多问题 因为我没有看到任何现实世界的应用 如果您想知道尝试使用正则表达式做某事是否徒劳
  • Ruby on Rails - 在包含 I18n 的 link_to 调用中嵌入额外的 HTML

    我正在尝试在 link to 调用中嵌入额外的 HTML 如本线程中所示在 link to 调用中嵌入额外的 HTML https stackoverflow com questions 9403256 embed additional h
  • “依赖系统的时区设置并不安全”

    我有一个一周前完成的脚本 没有任何问题或错误 今天 我再次测试 收到以下消息 严格标准 date function date 依赖并不安全 系统的时区设置 请使用 date timezone 设置 TZ 环境变量或 date default
  • Android 如何获取所有浏览器应用中的浏览历史记录?

    我想获取android手机中不同浏览器的所有浏览历史记录 也许您知道 一部手机中通常有多个浏览器应用程序 假设您的所有浏览器都使用此 API 来保存历史记录 这应该对您有用 http developer android com refere
  • Node.js sqlite3 IN 运算符

    所以我目前正在尝试在 Node js 中进行查询 friends is an array object db all SELECT email FROM users WHERE email in friends function err r
  • 颤振:缺少 google_app_id。 Firebase 分析已禁用

    我想从一个设备向另一个设备发送通知 但是当我发送它时 我进入了接收器设备 D FLTFireMsgReceiver 8876 broadcast received for message E FA 8876 Missing google a
  • 如何组合多个grep命令?

    我有一个很长的 txt 文件 LONG txt 在该 txt 文件中 我想搜索 3 种类型的模式 然后我想将 grep 结果捕获到一个新的 txt 文件中 SHORT txt 图案 AAAAA BBBBB CCCCC NOTE 当图案AAA
  • Vim 代码补全

    是否可以让 Vim 为您完成代码 就像在任何其他 IDE 中一样 不仅仅是单词搜索 还包括类成员 方法等 可用的最佳选项 插件有哪些 铿锵完成 http www vim org scripts script php script id 33
  • 如果消费者持有消息的时间超过自动提交间隔时间,kafka会丢失消息吗?

    假设自动提交间隔时间为 30 秒 消费者由于某种原因无法处理消息并保留消息超过 30 秒然后崩溃 自动提交偏移量机制是否会在消费者崩溃之前提交此偏移量 如果我的假设是正确的 消息会因其偏移量提交而丢失 但消息本身尚未被处理 让我们假设您的消
  • 使用 C++ 查找向量的中值

    我是一名编程学生 对于我正在从事的一个项目 我必须做的事情之一是计算 int 值向量的中值 并且必须通过将其传递给函数来完成 此外 向量最初是使用 C 随机生成器 mt19937 随机生成的 我已经在代码中写下了该生成器 我将使用排序函数和
  • 使用 json.net 对对象属性进行条件序列化/反序列化[重复]

    这个问题在这里已经有答案了 我有一个场景 其类定义如下 class MyObject public DataDictionary MyObjectData get set public bool ShouldSerializeMyObjec