2

我正在将一个缺少某些属性的 xml 文档传递给解串器。我需要在结果对象中将缺失值设为 null,但当前 ints 反序列化为零并且布尔值设为 false。

下面的示例显示了一个 vals 正确反序列化的文档,但没有 vals 的文档返回了零和空值。

如何强制反序列化器不要像这样处理缺失的属性。

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

namespace SOQuestion
{
    class Program
    {
        static void Main(string[] args)
        {

            var resultWithVals = getObject(docWithVals());
            var resultWithoutVals = getObject(docWithoutVals());

            Console.WriteLine("WITH VALS");
            Console.WriteLine(resultWithVals.someBool);
            Console.WriteLine(resultWithVals.someFloat);
            Console.WriteLine(resultWithVals.someInt);
            Console.WriteLine(resultWithVals.someString);


            Console.WriteLine("WITHOUT VALS"); // nulls are returned here as zero and false
            Console.WriteLine(resultWithoutVals.someBool);
            Console.WriteLine(resultWithoutVals.someFloat);
            Console.WriteLine(resultWithoutVals.someInt);
            Console.WriteLine(resultWithoutVals.someString);

            Console.ReadLine();


        }

        public static XmlDocument docWithVals()
        {
            var doc = new XmlDocument();
            var el = (XmlElement)doc.AppendChild(doc.CreateElement("Result"));
            el.SetAttribute("someString", "Hello World");
            el.SetAttribute("someBool", "true");
            el.SetAttribute("someInt", "1");
            el.SetAttribute("someFloat", "1.1");
            return doc;

        }

        public static XmlDocument docWithoutVals()
        {
            var doc = new XmlDocument();
            var el = (XmlElement)doc.AppendChild(doc.CreateElement("Result"));
            el.SetAttribute("someString", "Hello World");
            return doc;

        }


        public static Result getObject(XmlDocument doc)
        {

                var mySerializer = new XmlSerializer(new Result().GetType());
                var myStream = new MemoryStream();
                doc.Save(myStream);
                myStream.Position = 0;
                var r = mySerializer.Deserialize(myStream);
                return (Result)r;
         }

    }

    [Serializable]
    public class Result
    {
        [XmlAttribute]
        public string someString { get; set; }
        [XmlAttribute]
        public bool someBool { get; set; }
        [XmlAttribute]
        public int someInt { get; set; }
        [XmlAttribute]
        public float someFloat { get; set; }

    }

}
4

4 回答 4

2

您可以使用DefaultValueAttribute为未初始化的字段提供默认值。在你的情况下,你可以写

using System.ComponentModel;
using System.Configuration;

[XmlAttribute, DefaultValue(true)]
public bool someBool { get; set; }

编辑。请参阅MSDN 上的 MSND 页面注释上的注释:

DefaultValueAttribute不会导致成员使用属性值自动初始化。您必须在代码中设置初始值。

此问题也已在XML 序列化和 c# 中的 DefaultValue("") 相关问题中得到解决。因此,要设置默认值,您必须在代码中指定这些值。


我希望这有帮助。

于 2012-11-06T13:01:52.613 回答
0

您可以实现 ISerializable 接口并使用 GetObjectData 方法。

请检查自定义序列化

于 2012-11-06T15:49:30.723 回答
0

你可以尝试使用这样的东西:

    [XmlAttribute]
    public bool someBool { get; set; }
    [XmlIgnore]
    public bool someBoolSpecified { get; set; }
    [XmlIgnore]
    public bool? SomeBool
    {
        get
        {
            return someBoolSpecified ? someBool : default(bool?);
        }
        set
        {
            someBoolSpecified = value != default(bool?);
            someBool = value ?? default(bool);
        }
    }

根据XmlSerializer文档

另一种选择是使用特殊模式来创建 XmlSerializer 识别的布尔字段,并将 XmlIgnoreAttribute 应用于该字段。该模式以 propertyNameSpecified 的形式创建。例如,如果有一个名为“MyFirstName”的字段,您还将创建一个名为“MyFirstNameSpecified”的字段,它指示 XmlSerializer 是否生成名为“MyFirstName”的 XML 元素。这在以下示例中显示。

于 2012-11-06T18:03:02.680 回答
0

ints 和floats 不能有空值 - 它们的默认值分别是0false

如果它们应该被允许为空,则更改为可空类型:

[Serializable]
public class Result
{
    [XmlAttribute]
    public string someString { get; set; }
    [XmlAttribute]
    public bool? someBool { get; set; }
    [XmlAttribute]
    public int? someInt { get; set; }
    [XmlAttribute]
    public float? someFloat { get; set; }
}

HasValue请注意,使用此类型的任何内容现在都必须在使用这些字段和/或使用属性访问值之前首先使用检查空值Value

于 2012-11-06T15:39:29.223 回答