使用新属性的 NetDataContractSerializer 反序列化

2023-12-30

由于缺乏任何真正的远见,我已经使用 NetDataContractSerializer 序列化了仅使用 Serialized 修饰的大量数据,现在我想添加一个新字段。我有什么选择?

原始类看起来像这样(具有几个继承级别和相当多的字段):

[Serializable]
public class InheritedClass : BaseClass
{
    public string StringId { get; set; }
}

现在我想添加另一个属性,例如:

[Serializable]
public class InheritedClass : BaseClass
{
    public string StringId { get; set; }
    public int IntId { get; set; }
}

现在,当我更新类并进行反序列化时,我收到一个异常,因为新字段不存在,如下所示:

Exception thrown: 'System.Runtime.Serialization.SerializationException' in System.Runtime.Serialization.dll

Additional information: Error in line 1 position 601. 'Element' '_x003C_StringId_x003E_k__BackingField' from namespace 'http://schemas.datacontract.org/2004/07/QT' is not expected. Expecting element '_x003C_IntId_x003E_k__BackingField'.

好的,这是有道理的,因为 NetDataContractSerializer 需要相同的类。我可以使用 DataMember 属性来解决这个问题,例如:

[DataMember(IsRequired = false)]

那么问题是,切换到 DataMember(正如我应该预先完成的那样,或使用不同的序列化程序)会更改隐式字母顺序,然后我的大多数字段将默默地不会像众所周知的那样反序列化。

我尝试手动添加与磁盘上的顺序内联的顺序(通过Order属性上的属性),但这似乎也没有得到尊重。 (我也没有看到可以在原始 xml 中匹配的订单值。)

除了编写一些内容来加载 xml 并插入丢失的节点之外,还有其他选择吗? (或者等效地设置一个并行类型并从一个类型反序列化,然后重新序列化到另一个类型?)如果没有,我可能只会加载当前类型并反序列化为 JsonNet 或 protobuf,但是我是否错过了 DataMember/ 更直接的东西ETC?


标记类型为[Serializable]意味着该类型可以通过序列化其类型来序列化公共和私人领域 https://msdn.microsoft.com/en-us/library/ms973893.aspx——不是它的属性。NetDataContractSerializer https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.netdatacontractserializer?view=netframework-4.8#remarks如果存在此属性,则尊重该属性,并按指示序列化字段。为自动实现的属性 https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/auto-implemented-properties秘密支持字段是实际序列化的字段。

添加新字段时,处理遗留数据通常会用以下标记来标记它:[OptionalField] https://msdn.microsoft.com/en-us/library/system.runtime.serialization.optionalfieldattribute(v=vs.110).aspx表明它并不总是出现在序列化流中。在 c# 中7.3 https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7之后,可以通过使用以下方法对自动实现的属性的秘密支持字段执行此操作字段目标属性 https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-7.3/auto-prop-field-attrs:

[Serializable]
public class InheritedClass : BaseClass
{
    public string StringId { get; set; }

    [field: OptionalField]
    public int IntId { get; set; }
}    

在 c# 7.3 之前,无法将属性应用于自动实现的属性的支持字段。因此,您需要使支持字段显式并向其添加属性:

[Serializable]
public class InheritedClass : BaseClass
{
    public string StringId { get; set; }

    [OptionalField]
    int intId;

    public int IntId { get { return intId; } set { intId = value; } }
}    

Notes:

  • 正如问题中所指出的,如果类型标记为数据契约属性 https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-data-contracts then NetDataContractSerializer将优先使用那些默认值[Serializable]合同并允许您显式指示要序列化的属性(并提供比秘密支持字段名称更清晰的名称)。

    不幸的是,向遗留类型添加数据协定属性并不总是可行的。

  • NetDataContractSerializer 尚未移植到.NET Core / .NET 5 https://stackoverflow.com/q/53002135/3744182并且很可能永远不会 https://github.com/dotnet/runtime/issues/27763.

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

使用新属性的 NetDataContractSerializer 反序列化 的相关文章

  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 扩展 XSD 文件

    我有一个带有枚举类型的 XSD 文件 我想创建一个 扩展 XSD 文件 它添加一些额外的枚举 但其他方面的行为就像主 XSD 一样 例如 主 XSD 文件包含以下内容
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 在 Delphi 中使用 XML(将特定数据返回到变量)

    过去几天我一直在尝试使用 Delphi 2010 和 MSXML 我是一个极端的新手 需要一点指导 var MemoryStream TMemoryStream XMLPath String sName String XMLDoc vari
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐

  • C# 6.0 TFS 构建

    我正在 Visual Studio 2015 CTP 中试用 C 6 0 的新功能 但我的项目无法在 TFS 2013 中构建 并且视觉工作室在线 http www visualstudio com en us products what
  • 获取嵌入式 IronPython v2 中的最后一条语句结果

    Mike Stall 博客中的这篇文章 https web archive org web 20151031235957 http blogs msdn com 80 b jmstall archive 2005 09 01 howto e
  • 确定连接到 Qt 中给定插槽的信号

    我已将自己注入到 Qt 应用程序中 并试图找出给定插槽连接到的信号 但找不到任何有关执行此操作的信息 是否有一种开箱即用的机制可以做到这一点 如果是这样 这是否暴露给 QtScript 如果没有 我可以很容易地将其包裹起来 如果没有这样的机
  • 如何检测图像是照片、剪贴画还是线条画?

    识别图像类型的最佳方法是什么 rwong s https stackoverflow com users 377657 rwong answer https stackoverflow com a 3446199 18437 on 这个问题
  • 如何使 iFrame 在单击按钮时全屏显示?

    我想使用 JavaScript 通过单击按钮使 iFrame 显示在全屏上 您必须做两件事 使窗口全屏显示 然后填满整个尺寸 您可以使用 JS 使其全屏显示 例如这个答案 https stackoverflow com
  • 如何使用XMPP框架检索成员聊天室列表?

    如何使用XMPP框架检索聊天室的成员列表 我尝试使用 void xmppRoom XMPPRoom sender didFetchMembersList NSArray items 但它返回一个空数组 有人请帮帮我吗 当您加入房间委托时 x
  • 在 Haskell 中比较两个项的构造函数的一般方法[重复]

    这个问题在这里已经有答案了 给定某些数据类型的两个项 t1 t2 是否有某种方法可以检查 t1 和 t2 是否以相同的构造函数开头 而不需要对构造函数进行一些详尽的案例或模式匹配 就像如果我的类型是 Either a b 那么我想要 che
  • 如何创建 50 个州的地图(而不仅仅是 48 个州)

    如何用 R 制作 50 个州的地图 看起来人们创建的所有示例地图都只是 48 级以下的地图 有很多方法可以做到这一点 就我个人而言 我发现谷歌拥有最有吸引力的地图 我建议ggmap googleVis 和 或RgoogleMaps 例如 r
  • 测试 WebApi 控制器 Url.Link

    我有以下控制器操作 public void Post Dto model using var message new MailMessage var link Url Link ConfirmAccount new model Id mes
  • 在 Ruby 中导出环境变量

    如何将 Ruby 脚本中的环境变量导出到父 shell 例如 实现一个简单的实现readbash 内置 usr bin ruby varname ARGV 0 ENV varname STDIN gets but have varname
  • Eloquent - 更新集合中的所有模型

    我想在集合的所有模型中设置某个属性 在简单的 SQL 中 UPDATE table SET att foo WHERE id in 1 2 3 我的代码 models MyModel findMany 1 2 3 models gt upd
  • 在表单提交时保留选项选择下拉列表中的所有多选值

    我正在使用多选下拉菜单here https silviomoreto github io bootstrap select examples The
  • CamcorderProfile.QUALITY_HIGH 分辨率产生绿色闪烁视频

    到目前为止我还没有找到任何解释 基本上 我有一个视频录制类 当我的三星 Galaxy S2 上的 setVideoSize 设置为 720 x 480 时 它的工作效果非常好 我希望它以尽可能高的分辨率进行录制 因此使用 Camcorder
  • 结构体的部分初始化? [复制]

    这个问题在这里已经有答案了 是否可以静态初始化结构体的一部分 我的结构 struct data char name 20 float a int b char c 首字母缩写和打印时 struct data badge badge 307
  • 当我在 requirejs 中时,如何调用全局加载的 api?

    我继承了一个使用magento和foundation的项目 我在此之上合并了 requirejs 和主干 我试图让一个基础轨道画廊工作 该画廊正在通过主干中的霍根 渲染 加载到 dom 中 我遇到的问题是 基础已经在 magento 模板之
  • 失败 - 上下文路径 /Hello 处的应用程序无法启动

    我正在尝试在 Tomcat 6 0 中部署新的 Web 应用程序 但是每当我单击开始按钮时 我都会反复收到失败 上下文路径 Hello 处的应用程序无法启动 每当我单击开始按钮时 其他部署的应用程序都运行良好 但为什么不是这个应用程序呢 w
  • C# 应用程序中的非托管调用堆栈

    我在编写的非托管 dll 中遇到访问冲突错误 但是当我尝试在 C 应用程序中调试它时 它只会在 Visual Studio 的调试窗口中获取调用堆栈的最后一帧 我将 debug gt exceptions gt System AccessV
  • 如何检查 Clang ASTvisitor 中的变量声明是否是数组

    我试图确定 ASTvisitor 中的变量声明是否是一个数组 如果是一个数组 我想确定该数组的维数 您可以在下面找到我的代码 bool VisitVarDecl VarDecl var if astContext gt getSourceM
  • 在spark中的子字符串中使用长度函数

    我正在尝试在子字符串函数中使用长度函数DataFrame但它给出了错误 val substrDF testDF withColumn newcol substring col 1 length col 1 下面是错误 error type
  • 使用新属性的 NetDataContractSerializer 反序列化

    由于缺乏任何真正的远见 我已经使用 NetDataContractSerializer 序列化了仅使用 Serialized 修饰的大量数据 现在我想添加一个新字段 我有什么选择 原始类看起来像这样 具有几个继承级别和相当多的字段 Seri