[ACCEPTED]-How to make a value type nullable with .NET XmlSerializer?-value-type
I just discovered this. XmlSerialier
looks for a XXXSpecified
boolean 11 property to determine if it should be included. This 10 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; }
}
Proof:
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>
}
Edit: Yes, it 9 is a documented feature. See the MSDN entry for XmlSerializer
Another 8 option is to use a special pattern to create 7 a Boolean field recognized by the XmlSerializer, and 6 to apply the XmlIgnoreAttribute to the field. The 5 pattern is created in the form of propertyNameSpecified. For 4 example, if there is a field named "MyFirstName" you 3 would also create a field named "MyFirstNameSpecified" that 2 instructs the XmlSerializer whether to generate 1 the XML element named "MyFirstName".
Extending Samuel's answer and Greg Beech's 10 comment to the case of a boolean property: if 9 the property is of type bool then you can't 8 write a simple test in the propertySpecified 7 property.
A solution is to use a Nullable<bool> type, then 6 the test in the propertySpecified property 5 is simply property.HasValue. e.g.
using System.Xml.Serialization;
public class Person
{
public bool? Employed { get; set; }
[XmlIgnore]
public bool EmployedSpecified { get { return Employed.HasValue; } }
}
An alternative 4 to using a nullable type for a numeric property 3 (suggested by Greg Beech) is to set the 2 value property to an invalid default value, such 1 as -1, as follows:
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; } }
}
You can use XmlElementAttribute.IsNullable:
[Serializable]
public class MyClass
{
[XmlElement(IsNullable = true)]
public int? Age { get; set; }
public int MyClassB { get; set; }
}
0
This should help
Make Age int?
and..
public bool ShouldSerializeAge() { return Age.HasValue; }
..it does 2 mean adding the ShouldSerializeXXX methods 1 to your class!
You need to do custom XML serialization; see 1 IXmlSerializer.
public class MyClass : IXmlSerializable
{
public int Age { get; set; }
public MyClassB MyClassB { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
// http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx
return null;
}
public void ReadXml(XmlReader reader)
{
if (reader.IsStartElement("Age"))
Age = reader.ReadContentAsInt();
var serializer = new XmlSerializer(typeof(MyClassB));
MyClassB = (MyClassB)serializer.Deserialize(reader);
}
public void WriteXml(XmlWriter writer)
{
if (Age > 0)
{
writer.WriteStartElement("Age");
writer.WriteValue(Age);
writer.WriteEndElement();
}
var serializer = new XmlSerializer(typeof(MyClassB));
serializer.Serialize(writer, MyClassB);
}
}
Forget about Nullable ... ShouldSerializeXXX 2 is a pretty solution. Here Age will be serialized 1 upon your condition.
[Serializable]
public class MyClass
{
public int Age { get; set; }
public int MyClassB { get; set; }
#region Conditional Serialization
public bool ShouldSerializeAge() { return age > 0; }
#endregion
}
[Serializable]
public class MyClassB
{
public int RandomNumber { get; set; }
}
xsd.exe will autogenerate the XXXSpecified 3 property and accessors if you set the 'minoccurs' attribute 2 as 'minoccurs="0"' for an element ... if 1 you are using a schema to define your xml/class
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.