XML将null属性反序列化为零和false

时间:2012-11-06 12:56:06

标签: c# xml-serialization

我正在将一个缺少某些属性的xml doc传递给deserilaliser。我需要在结果对象中将缺少的值设置为null,但是当前将反序列化为零并且将bools设置为false。

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

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

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 个答案:

答案 0 :(得分:2)

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

using System.ComponentModel;
using System.Configuration;

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

编辑。请参阅MSND页面note on MSDN上的说明:

  

DefaultValueAttribute将导致   会员是自动的   用属性初始化   值。您必须设置初始值   在你的代码中。

此问题也已在XML serialization and DefaultValue("") related problem in c#中得到解决。 因此,要设置默认值,您必须在代码中指定这些值。


我希望这会有所帮助。

答案 1 :(得分:0)

intfloat s不能包含空值 - 它们的默认值分别为0false

如果允许它们为null,则将其更改为可空类型:

[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属性访问值。

答案 2 :(得分:0)

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

请检查Custom Serialization

答案 3 :(得分: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 documentation

  

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