我正在将一个缺少某些属性的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; }
}
}
答案 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)
int
和float
s不能包含空值 - 它们的默认值分别为0
和false
。
如果允许它们为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方法。
答案 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元素。这在以下示例中显示。