0

I am using XmlConvert. For the one instance of Class, only one property will have a value, another will be empty.

public class Class
{
    [XmlAttribute("ValueA")]
    public decimal? ValueA { get; set; }

    [XmlAttribute("ValueB")]
    public decimal? ValueB { get; set; }
}

The problem here is that the serializer can't serialize null property. How can I show only one property with value? Example:

var item = new Class { ValueA = 1, ValueB = null}

<?xml version="1.0" encoding="utf-8"?>
<model>
    <ValueA>1</ValueA>
</model>
Basil Kosovan
  • 888
  • 1
  • 7
  • 30
  • I think you’re looking for the ShouldSerializeValueB pattern to determine whether it should be serialised. – ekke Dec 29 '20 at 15:58
  • 4
    Does this answer your question? [Xml serialization - Hide null values](https://stackoverflow.com/questions/5818513/xml-serialization-hide-null-values) – ekke Dec 29 '20 at 15:59
  • Cannot serialize member 'ValueB ' of type System.Nullable`1[System.Decimal]. XmlAttribute/XmlText cannot be used to encode complex types. – Basil Kosovan Dec 29 '20 at 16:43
  • Even if ValueB has a value it will not work, It's not allowed to have 'type?' with XmlAttribute, maybe it's allowed with XMLElement – Basil Kosovan Dec 29 '20 at 16:56
  • `1` is element, not attribute. So use `[XmlElement("ValueA")]`. – Alexander Petrov Dec 29 '20 at 19:12

1 Answers1

2

You will need to wrap your nullable properties to get it work. For example, for your ValueA

public class Class
{
    [XmlIgnore]
    public decimal? ValueA { get; set; }

    [XmlAttribute("ValueA")]
    public decimal ValueAUnwrapped
    {
        //this will only called, when ShouldSerializeValueAUnwrapped return trues, so no NRE here
        get => ValueA.Value; 
        set => ValueA = value;
    }
    
    public bool ShouldSerializeValueAUnwrapped() => ValueA.HasValue;
}

This code instructs serializer to serialize ValueAUnwrapped property only when the original ValueA property has value. This is achieved by adding ShouldSerialize<Name>() function which serializer will call for corresponding Name property: https://learn.microsoft.com/en-us/dotnet/desktop/winforms/controls/defining-default-values-with-the-shouldserialize-and-reset-methods?view=netframeworkdesktop-4.8

You will also need to pereform the same trick for the ValueB.

Serg
  • 3,454
  • 2
  • 13
  • 17