9

I am using Web API with DataContract serialization. The output looks like this:

<Data>
<Status>
  <Date>2014-08-13T00:30:00</Date>
  <ID>312</ID>
  <Option>No Limitation</Option>
  <Value i:nil="true" />
</Status>
<Status>
  <Date>2014-08-13T01:00:00</Date>
  <ID>312</ID>
  <Option>No Limitation</Option>
  <Value i:nil="true" />
</Status>
<Status>
  <Date>2014-08-13T01:30:00</Date>
  <ID>312</ID>
  <Option>No Limitation</Option>
  <Value i:nil="true" />
</Status>
<Status>
  <Date>2014-08-13T02:00:00</Date>
  <ID>312</ID>
  <Option>No Limitation</Option>
  <Value i:nil="true" />
</Status>

I was able to remove all the extra namespaces by doing:

[DataContract(Namespace="")]
public class Status

But the only attribute left is the i:nil attribute. What should i do in order to remove the i:nil attribute?

ronen
  • 1,460
  • 2
  • 17
  • 35
  • 1
    Would this solve your problem: http://stackoverflow.com/questions/12465285/conditional-datacontract-serialization-in-webapi, `DataMember(EmitDefaultValue = false)]` – Prescott Aug 17 '14 at 07:25
  • @Prescott, that will remove the empty element at all. What I want is to show the element without the `i:nil` attribute. – ronen Aug 17 '14 at 08:42

2 Answers2

6

You need to set the EmitDefaultValue property in the DataMember attribute

[DataMember(EmitDefaultValue = false)]

Be sure not to set this attribute on members that have the IsRequired = true set to them.

Edit

You may also iterate the XML manually and remove the nil attributes using LINQ 2 XML:

XNamespace i = "http://www.w3.org/2001/XMLSchema-instance";
        XDocument xdoc = XDocument.Load(@"XmlHere"); // This may be replaced with XElement.Parse if the XML is in-memory

        xdoc.Descendants()
                 .Where(node => (string)node.Attribute(i + "nil") == "true")
                 .Remove();
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
4

What you want is to make the code "think" that instead of having a null value, it actually has an empty string. You can do that by being a little smart with the property getter (see below). Just remember to add a comment explaining why you're doing that so other people who will maintain the code know what's going on.

[DataContract(Namespace = "")]
public class Status
{
    [DataMember]
    public DateTime Date { get; set; }

    [DataMember]
    public int ID { get; set; }

    [DataMember]
    public string Option { get; set; }

    private string value;

    [DataMember]
    public string Value
    {
        get { return this.value ?? ""; }
        set { this.value = value; }
    }
}
carlosfigueira
  • 85,035
  • 14
  • 131
  • 171