Suppress Null Value Types from Being Emitted by XmlSerializer
Try adding:
public bool ShouldSerializeAmount() {
return Amount != null;
}
There are a number of patterns recognised by parts of the framework. For info, XmlSerializer
also looks for public bool AmountSpecified {get;set;}
.
Full example (also switching to decimal
):
using System;
using System.Xml.Serialization;
public class Data {
public decimal? Amount { get; set; }
public bool ShouldSerializeAmount() {
return Amount != null;
}
static void Main() {
Data d = new Data();
XmlSerializer ser = new XmlSerializer(d.GetType());
ser.Serialize(Console.Out, d);
Console.WriteLine();
Console.WriteLine();
d.Amount = 123.45M;
ser.Serialize(Console.Out, d);
}
}
More information on ShouldSerialize* on MSDN.
How to exclude null properties when using XmlSerializer
I suppose you could create an XmlWriter that filters out all elements with an xsi:nil attribute, and passes all other calls to the underlying true writer.
Serialize a nullable int
XmlSerializer supports the ShouldSerialize{Foo}()
pattern, so you can add a method:
public bool ShouldSerializeID() {return ID.HasValue;}
There is also the {Foo}Specified
pattern - not sure if XmlSerializer supports that one.
WebAPI: Null values not suppressed by Default XML Serializer
This declarative tag - [XmlElement(IsNullable = false)] - is honored by the XmlSerializer, but ignored by the DataContractSerializer. If you want to use this tag you need to explicitly select the XmlSerializer. As follows:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
...
config.Formatters.XmlFormatter.UseXmlSerializer = true;
...
}
}
How to make a value type nullable with .NET XmlSerializer?
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; }
}
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 is a documented feature. See the MSDN entry for XmlSerializer
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".
Related Topics
Easy Creation of Properties That Support Indexing in C#
Intersect with a Custom Iequalitycomparer Using Linq
Automatic Cookie Handling C#/.Net Httpwebrequest+Httpwebresponse
Determine Client's Computer Name
How to Login/Authenticate a User with ASP.NET MVC5 Rtm Bits Using Aspnet.Identity
Print the Source Filename and Linenumber in C#
Dynamic Button Creation & Placing Them in a Predefined Order Using C#
Is Graphics.Drawimage Too Slow for Bigger Images
Custom Xmlwriter to Skip a Certain Element
Using Moq to Mock an Asynchronous Method for a Unit Test
Conversion of a Decimal to Double Number in C# Results in a Difference
Why Can't C# Use Inline Anonymous Lambdas or Delegates
How to Prevent an Exception in a Background Thread from Terminating an Application