問題描述
假設(shè)我有這個(gè)對象:
[Serializable]
public class MyClass
{
public int Age { get; set; }
public int MyClassB { get; set; }
}
[Serializable]
public class MyClassB
{
public int RandomNumber { get; set; }
}
XmlSerializer 將像這樣序列化對象:
The XmlSerializer will serialize the object like that:
<MyClass>
<Age>0</age>
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
如何使屬性 Age 可以為空?IE:當(dāng)屬性年齡小于 0 時(shí)不序列化它?
How can I made the property Age nullable? IE: to not serialize the property Age when it's under 0?
我嘗試使用 Nullable,但它會像這樣序列化我的對象:
I tried with the Nullable, but it serialize my object like that:
<MyClass>
<Age d5p1:nil="true" />
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
通過閱讀 MSDN 文檔,我發(fā)現(xiàn)了這一點(diǎn):
By reading the MSDN documentation I found this:
您不能將 IsNullable 屬性應(yīng)用于鍵入為值類型的成員,因?yàn)橹殿愋筒荒馨?nullNothingnullptra 空引用(在 Visual Basic 中為 Nothing).此外,對于可為空的值類型,您不能將此屬性設(shè)置為 false.當(dāng)此類類型為 nullNothingnullptra 空引用(在 Visual Basic 中為 Nothing)時(shí),將通過將 xsi:nil 設(shè)置為 true 來序列化它們.
You cannot apply the IsNullable property to a member typed as a value type because a value type cannot contain nullNothingnullptra null reference (Nothing in Visual Basic). Additionally, you cannot set this property to false for nullable value types. When such types are nullNothingnullptra null reference (Nothing in Visual Basic), they will be serialized by setting xsi:nil to true.
來源:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlelementattribute.isnullable.aspx
我知道不能將值類型設(shè)置為 null.值類型總是被設(shè)置為某物.序列化不能根據(jù)它的當(dāng)前值來決定是否序列化它.
I understand a value type can't be set to null. A valuetype is always set to something. The serialization can't make the decision to serialize it or not based on it's current value.
我嘗試使用這些屬性,但沒有成功.我嘗試創(chuàng)建一個(gè) agecontainer 對象并使用屬性操作它的序列化,但沒有成功.
I tried with the attributes, but it didn't work out. I tried creating an agecontainer object and manipulate it's serialization with attributes, but it didn't work out.
我真正想要的是:
<MyClass>
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
當(dāng)屬性年齡低于 0(零)時(shí).
When the property Age is below 0 (zero).
看起來您必須實(shí)現(xiàn)自定義序列化.
Looks like you'll have to implement custom serialization.
是的,我也這么認(rèn)為,但我想沒有它就離開.
Yeah, that's what I though too, but I'd like to get away without it.
在應(yīng)用中,對象要復(fù)雜得多,我不想自己處理序列化.
In the application, the object is much more complex, and I would like to not handle the serialization myself.
推薦答案
我剛剛發(fā)現(xiàn)了這個(gè).XmlSerialier
查找 XXXSpecified
布爾屬性以確定是否應(yīng)包含它.這應(yīng)該可以很好地解決問題.
I just discovered this. XmlSerialier
looks for a XXXSpecified
boolean property to determine if it should be included. This should solve the problem nicely.
[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; }
}
證明:
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>
}
編輯:是的,這是一個(gè)記錄在案的功能.請參閱 MSDN 條目 XmlSerializer
Edit: Yes, it is a documented feature. See the MSDN entry for XmlSerializer
另一種選擇是使用特殊模式創(chuàng)建 XmlSerializer 識別的布爾字段,并將 XmlIgnoreAttribute 應(yīng)用于該字段.該模式以propertyNameSpecified 的形式創(chuàng)建.例如,如果有一個(gè)名為MyFirstName"的字段,您還將創(chuàng)建一個(gè)名為MyFirstNameSpecified"的字段,以指示 XmlSerializer 是否生成名為MyFirstName"的 XML 元素.
Another option is to use a special pattern to create a Boolean field recognized by the XmlSerializer, and to apply the XmlIgnoreAttribute to the field. The pattern is created in the form of propertyNameSpecified. For example, if there is a field named "MyFirstName" you would also create a field named "MyFirstNameSpecified" that instructs the XmlSerializer whether to generate the XML element named "MyFirstName".
這篇關(guān)于如何使用 .NET XmlSerializer 使值類型可以為空?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!