草庐IT

c# - 具有新属性的 NetDataContractSerializer 反序列化

coder 2024-07-01 原文

由于缺乏远见,我使用 NetDataContractSerializer 序列化了大量仅使用 Serializable 装饰的数据,现在我想添加一个新字段。我有哪些选择?

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

[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] 标记一个类型意味着可以通过序列化它的类型来序列化该类型 public and private fields -- 不是它的属性。 NetDataContractSerializer在存在时尊重此属性,按指示序列化字段。对于 auto-implemented property secret 支持字段是实际序列化的内容。

添加新字段时,处理遗留数据的一般做法是用[OptionalField]标记它。表明它不会总是出现在序列化流中。在 c# 7.3 中以后,可以通过使用 field-targeted attribute 对自动实现的属性的 secret 支持字段执行此操作:

[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; } }
}    

注意事项:

  • 如问题中所述,如果类型标记为 data contract attributes然后 NetDataContractSerializer 将优先使用默认的 [Serializable] 协定,并允许您明确指示要序列化的属性(并提供比 secret 支持字段名称更清晰的名称)。

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

  • NetDataContractSerializer has not been ported to .NET Core / .NET 5很可能never will be .

关于c# - 具有新属性的 NetDataContractSerializer 反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33813551/

有关c# - 具有新属性的 NetDataContractSerializer 反序列化的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  5. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  6. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  7. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  8. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  9. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  10. ruby-on-rails - Rails 3.1 中具有相同形式的多个模型? - 2

    我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#

随机推荐