Jea*_*ois 29 c# null xml-serialization value-type
让我们假设我有这个对象:
[Serializable]
public class MyClass
{
public int Age { get; set; }
public int MyClassB { get; set; }
}
[Serializable]
public class MyClassB
{
public int RandomNumber { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
XmlSerializer会像这样序列化对象:
<MyClass>
<Age>0</age>
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
Run Code Online (Sandbox Code Playgroud)
我怎样才能使该物业成为可空?IE:当它低于0时,没有序列化属性Age?
我尝试使用Nullable,但它将我的对象序列化为:
<MyClass>
<Age d5p1:nil="true" />
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
Run Code Online (Sandbox Code Playgroud)
通过阅读MSDN文档,我发现了这个:
您不能将IsNullable属性应用于键入为值类型的成员,因为值类型不能包含nullNothingnullptra null引用(在Visual Basic中为Nothing).此外,对于可空值类型,您不能将此属性设置为false.当这些类型为nullNothingnullptra null引用(在Visual Basic中为Nothing)时,它们将通过将xsi:nil设置为true来序列化.
来源:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlelementattribute.isnullable.aspx
我理解值类型不能设置为null.值类型始终设置为某个值.序列化不能根据它的当前值决定是否序列化它.
我尝试了属性,但它没有成功.我尝试创建一个agecontainer对象并使用属性操作它的序列化,但它没有成功.
我真正想要的是:
<MyClass>
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
Run Code Online (Sandbox Code Playgroud)
当属性Age低于0(零)时.
看起来你必须实现自定义序列化.
是的,那也是我的意思,但我想在没有它的情况下逃脱.
在应用程序中,对象要复杂得多,我不想自己处理序列化.
Sam*_*uel 56
我刚发现了这个.XmlSerialier查找XXXSpecified布尔属性以确定是否应包含它.这应该很好地解决问题.
[Serializable]
public class MyClass
{
public int Age { get; set; }
[XmlIgnore]
public bool AgeSpecified { get { return Age >= 0; } }
public int MyClassB { get; set; }
}
[Serializable]
public class MyClassB
{
public int RandomNumber { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
证明:
static string Serialize<T>(T obj)
{
var serializer = new XmlSerializer(typeof(T));
var builder = new StringBuilder();
using (var writer = new StringWriter(builder))
{
serializer.Serialize(writer, obj);
return builder.ToString();
}
}
static void Main(string[] args)
{
var withoutAge = new MyClass() { Age = -1 };
var withAge = new MyClass() { Age = 20 };
Serialize(withoutAge); // = <MyClass><MyClassB>0</MyClassB></MyClass>
Serialize(withAge); // = <MyClass><Age>20</Age><MyClassB>0</MyClassB></MyClass>
}
Run Code Online (Sandbox Code Playgroud)
编辑:是的,这是一个记录的功能.请参阅MSDN条目XmlSerializer
另一种选择是使用特殊模式创建XmlSerializer可识别的布尔字段,并将XmlIgnoreAttribute应用于该字段.该模式以propertyNameSpecified的形式创建.例如,如果有一个名为"MyFirstName"的字段,您还将创建一个名为"MyFirstNameSpecified"的字段,该字段指示XmlSerializer是否生成名为"MyFirstName"的XML元素.
小智 13
将Samuel的答案和Greg Beech的评论扩展到布尔属性的情况:如果属性是bool类型,那么你就不能在propertySpecified属性中编写一个简单的测试.
解决方案是使用Nullable <bool>类型,然后propertySpecified属性中的测试只是property.HasValue.例如
using System.Xml.Serialization;
public class Person
{
public bool? Employed { get; set; }
[XmlIgnore]
public bool EmployedSpecified { get { return Employed.HasValue; } }
}
Run Code Online (Sandbox Code Playgroud)
对数值属性使用可空类型(由Greg Beech建议)的替代方法是将value属性设置为无效的默认值,例如-1,如下所示:
using System.ComponentModel;
using System.Xml.Serialization;
public class Person
{
[DefaultValue(-1)]
public int Age { get; set; }
[XmlIgnore]
public bool AgeSpecified { get { return Age >= 0; } }
}
Run Code Online (Sandbox Code Playgroud)
您可以使用XmlElementAttribute.IsNullable:
[Serializable]
public class MyClass
{
[XmlElement(IsNullable = true)]
public int? Age { get; set; }
public int MyClassB { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33983 次 |
| 最近记录: |