Search code examples
c#inheritanceserializationxml-serializationdatacontractserializer

DataContractSerialization and the new keyword inheritance


I have an issue where a XML element "Event" is being serialized twice because of the new keyword. I want the derived type to only be serialized.

[DataContract(Name = "Division", Namespace = "")]
    public class ApiTeamDivision : ApiDivision
    {
        [DataMember]
        public new ApiTeamEvent Event { get; set; }
        [JsonIgnore]
        public new ApiDivisionSettings Settings { get; set; }
        [JsonIgnore]
        public new List<ApiPrice> Prices { get; set; }
        [JsonIgnore]
        public new List<ApiTeam> Teams { get; set; }
        [JsonIgnore]
        public new List<ApiAsset> Assets { get; set; }
        [JsonIgnore]
        public new List<ApiBracket> Brackets { get; set; }
    }   

<Division>
<Age>17</Age>
<Event i:nil="true"/>
<Event>
   <Address i:nil="true"/>
   <Assets i:nil="true"/>
   <Description i:nil="true"/>
   <Divisions i:nil="true"/>
</Event>
</Division>

Solution

  • Don't mark [DataMember] on the property Event in base class ApiDivision

    class ApiDivision
    {
        //[DataMember] => don't mark this
        public new ApiTeamEvent Event { get; set; }
    }
    

    For more, if you use [DataContract], no need to use attribute [JsonIgnore], because it is used for both format: json and Xml.

    So, if you want to ignore property in serialization, just don't mark it with attribute [DataMember]

    [DataContract(Name = "Division", Namespace = "")]
    public class ApiTeamDivision : ApiDivision
    {
        [DataMember]
        public new ApiTeamEvent Event { get; set; }
    
        public new ApiDivisionSettings Settings { get; set; }
    
        public new List<ApiPrice> Prices { get; set; }
    
        public new List<ApiTeam> Teams { get; set; }
    
        public new List<ApiAsset> Assets { get; set; }
    
        public new List<ApiBracket> Brackets { get; set; }
    }
    

    Edit:

    Or you can use (IsRequired=false, EmitDefaultValue=false) to ignore if property is null:

    class ApiDivision
    {
        [DataMember(IsRequired=false, EmitDefaultValue=false)]
        public new ApiTeamEvent Event { get; set; }
    }