c# - 在 C# 中,如何将旧对象中的 XML 反序列化为更新后的对象并忽略丢失的 xml 元素?

标签 c# xml-serialization defaults

我有一个自定义设置文件,我使用 XmlSerializer 对其进行序列化/反序列化。我的对象定义中没有定义模式和序列化标签,只是直接对象序列化(尽管我会在需要时添加它们)。

我的问题是我需要向对象添加数据成员。如果我这样做,我知道旧的设置文件将不会反序列化。

有没有一种方法可以为添加的成员指定默认值,或者如果 XML 中缺少它们,可以通过一些简单的方法忽略它们?

最佳答案

来自 MSDN

Best Practices To ensure proper versioning behavior, follow these rules when modifying a type from version to version:

  • When adding a new serialized field, apply the OptionalFieldAttribute attribute.

  • When removing a NonSerializedAttribute attribute from a field (that was not serializable in a previous version), apply the OptionalFieldAttribute attribute.

  • For all optional fields, set meaningful defaults using the serialization callbacks unless 0 or null as defaults are acceptable.

我已经尝试模拟您的情况,在新版本的类中有一个名为 Element2 的新成员。将我的新成员初始化为“这是新成员”这里是完整的证明

Test1 假定您使用 Root 类的旧定义与 Just one Element1 进行序列化

Test2 当你使用根类的新定义序列化和反序列化时

要以任何方式回答您的问题以提供默认值,您应该使用“OptionalField”

using System;
using System.Runtime.Serialization;
using System.IO;

public class Test
{

  [Serializable]
  public class Root
  {
    [OptionalField(VersionAdded = 2)] // As recommended by Microsoft
    private string mElement2 = "This is new member";
    public String Element1 { get; set; }    
    public String Element2 { get { return mElement2; } set { mElement2 = value; } }
  }

  public static void Main(string[] s)
  {
    Console.WriteLine("Testing serialized with old definition of Root ");
    Console.WriteLine(" ");
    Test_When_Original_Object_Was_Serialized_With_One_Element();
    Console.WriteLine(" ");
    Console.WriteLine("Testing serialized with new definition of Root ");
    Console.WriteLine(" ");
    Test_When_Original_Object_Was_Serialized_With_Two_Element();
    Console.ReadLine();
  }

  private static void TestReadingObjects(string xml)
  {
    System.Xml.Serialization.XmlSerializer xmlSerializer =
    new System.Xml.Serialization.XmlSerializer(typeof(Root));


    System.IO.Stream stream = new MemoryStream();
    System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
    Byte[] bytes = encoding.GetBytes(xml);
    stream.Write(bytes, 0, bytes.Length);
    stream.Position = 0;
    Root r = (Root)xmlSerializer.Deserialize(stream);

    Console.WriteLine(string.Format("Element 1 = {0}", r.Element1));

    Console.WriteLine(string.Format("Element 2 = {0}", r.Element2 == null ? "Null" : r.Element2));
  }
  private static void Test_When_Original_Object_Was_Serialized_With_One_Element()
  {
    TestReadingObjects(@"<Root>   <Element1>1</Element1>   </Root>");
  }

  private static void Test_When_Original_Object_Was_Serialized_With_Two_Element()
  {
    TestReadingObjects(@"<Root>   <Element1>1</Element1> <Element2>2</Element2>   </Root>");
  }
}

//这里是输出 enter image description here

关于c# - 在 C# 中,如何将旧对象中的 XML 反序列化为更新后的对象并忽略丢失的 xml 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8174927/

相关文章:

javascript - 多个实例上的 jQuery 插件设置

ios - 在iOS上设置默认 session 长度?

c# - X509Certificate2 - 如果使用 ECC 证书,则拒绝访问异常

c# - XMLSerializer 没有正确地为 List 类型的属性反序列化 XML

python - 如何将 Python 对象序列化为 XML?

c++ - 在 MFC C++ 中创建 XmlSerializer

c# - 为什么不对 switch 语句强制执行显式 fall-through 而不是显式 break?

c# - 如何从 IHTMLDocument2 获取所有 mshtml.IHTMLDivElement?

c# - 查找数字与特定数字集的所有加法组合的算法?

c# - c# Winforms 中的 Web 浏览器