XmlSerializer定义默认值

时间:2011-09-03 01:35:22

标签: c# xmlserializer

我们有一个带有一些用户设置的xml文档。我们刚添加了一个新设置(在旧版xml文档中找不到),XmlSerializer会自动将其设置为false。 我试过DefaultValueAttribute,但它没有用。有关如何将默认值设为true的任何想法?这是代码:

private bool _property = true;
[DefaultValueAttribute(true)]
public bool Property 
{
    get { return _property; }
    set
    {
        if (_property != value)
        {
            _property = value;
            this.IsModified = true;
        }
    }
}

谢谢!

5 个答案:

答案 0 :(得分:9)

DefaultValue会影响序列化,只要在运行时属性的值与DefaultValue所说的值相匹配,那么XmlSerializer就不会实际写出该元素(因为它是默认值)。

我不确定它是否会影响读取时的默认值,但在快速测试中似乎不会这样做。在你的场景中,我可能只是将它作为一个带有支持字段的属性,其中字段初始值设定项使其为“true”。恕我直言,我比ctor方法更喜欢它,因为它将它与你做或不为课程定义的ctors分离,但它是同一个目标。

using System;
using System.ComponentModel;
using System.Xml.Serialization;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        var serializer = new XmlSerializer(typeof(Testing));

        string serializedString;
        Testing instance = new Testing();
        using (StringWriter writer = new StringWriter())
        {
            instance.SomeProperty = true;
            serializer.Serialize(writer, instance);
            serializedString = writer.ToString();
        }
        Console.WriteLine("Serialized instance with SomeProperty={0} out as {1}", instance.SomeProperty, serializedString);
        using (StringReader reader = new StringReader(serializedString))
        {
            instance = (Testing)serializer.Deserialize(reader);
            Console.WriteLine("Deserialized string {0} into instance with SomeProperty={1}", serializedString, instance.SomeProperty);
        }
        Console.ReadLine();
    }
}

public class Testing
{
    [DefaultValue(true)]
    public bool SomeProperty { get; set; }
}

正如我在评论中提到的,xml序列化属性页面(http://msdn.microsoft.com/en-us/library/83y7df3e.aspx)声称DefaultValue确实会使序列化程序设置值当它丢失时,但在此测试代码中没有这样做(与上面类似,但只是反序列化3个输入)。

using System;
using System.ComponentModel;
using System.Xml.Serialization;
using System.IO;

class Program
{
    private static string[] s_inputs = new[]
    {
        @"<?xml version=""1.0"" encoding=""utf-16""?>
          <Testing xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" />",

        @"<?xml version=""1.0"" encoding=""utf-16""?>
          <Testing xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
              <SomeProperty />
          </Testing>",

        @"<?xml version=""1.0"" encoding=""utf-16""?>
          <Testing xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
              <SomeProperty>true</SomeProperty>
          </Testing>",
    };

    static void Main(string[] args)
    {
        var serializer = new XmlSerializer(typeof(Testing));

        foreach (var input in s_inputs)
        {
            using (StringReader reader = new StringReader(input))
            {
                Testing instance = (Testing)serializer.Deserialize(reader);
                Console.WriteLine("Deserialized string \n{0}\n into instance with SomeProperty={1}", input, instance.SomeProperty);
            }
        }
        Console.ReadLine();
    }
}

public class Testing
{
    [DefaultValue(true)]
    public bool SomeProperty { get; set; }
}

答案 1 :(得分:3)

无论文档记录如何工作,我也没有看到在反序列化时分配DefaultValue。我的解决方案只是在类构造函数中设置默认值并放弃DefaultValueAttribute。

答案 2 :(得分:1)

关于斯科特的最后答复。

默认构造函数在没有找到元素时将任何数组属性设置为“null”。我已经将属性设置为一个新的空数组(所以是一个空数组的实例),但XmlSerializer在进行反序列化时绕过它并将其设置为“null”。

班级示例:

[XmlElement("Dtc")]
public DtcMarketMapping[] DtcMarketMappingInstances
{
    get { return dtcMarketMappingInstances; }
    set { dtcMarketMappingInstances = value; }
}

但它可能是数组特有的,你的答案仍然有效,可以在类的构造函数中将默认值设置为简单属性。

无论如何,感谢大家的答案。

答案 3 :(得分:0)

在构造函数中设置默认值。只有在文件中存在该值时,才会在反序列化期间更改该值。

public class MySettingsClass
{
    public MySettingsClass()
    {
        _property = true;
    }

    private bool _property = true;
    public bool Property 
    {
        get { return _property; }
        set
        {
            if (_property != value)
            {
                _property = value;
                this.IsModified = true;
            }
        }
    }
}

答案 4 :(得分:-1)

DefaultValueAttribute实际上对您正在运行的代码没有任何作用。它(主要)由属性浏览器使用(例如当您将对象绑定到PropertyGrid时)以了解默认值应该是什么,以便当值不同于默认值时,它们可以执行“特殊”操作。这就是Visual Studio中的属性网格如何知道何时使值变为粗体(表明它与默认值不同。

XmlSerializer将您的_property字段设置为false,因为这是bool的.NET Framework默认值。

实现这一目标的最简单方法可能是使用默认的类构造函数并在那里设置值。