Search code examples
c#xmlserializationdatacontractserializer

C# object<->Data Contract serialization/deserialization adds some unwanted tags


I'm facing an annoying situation where my serialization/deserialization isn't as expected.

I want

<OuterClass>
  <Assets>
      <Asset>Asset_A</Asset>
      <Asset>Asset_B</Asset>
  </Assets>
  ...
</OuterClass> 

but I'm getting

<OuterClass>
  <Assets>
    <Asset>
      <Asset>Asset_A</Asset>
    </Asset>
    <Asset>
      <Asset>Asset_B</Asset>
    </Asset>
  </Assets>
  ...
</OuterClass>

As you can see the Asset tag comes twice.

The code doing this is ..

public class OuterClass
{
    [DataMember(Name = "Assets", Order = 10)]
    public List<AssetClass> Assets { get; set; }
    ...
    [DataContract(Name = "Asset", Namespace = "")]
    public class AssetClass
    {
        [DataMember(Name = "Asset", Order = 10)]
        public string Asset { get; set; }
        ...
    } 
}

I know I've listed 'Name="Asset"' twice in the code too, but if I take out either of them, the framework adds it's own name inside there still screwing it up. Somehow I suspect I need to change the structure of the code itself but not sure how to do that.

(edit) I'm using the in-framework serialization/deserialization helpers. The code for that is (simplified):

public string ToXmlString(OuterClass AssetsWrapper)
{
    DataContractSerializer ser = new DataContractSerializer(typeof(OuterClass));            
    MemoryStream memStream = new MemoryStream();

    // Convert object -> stream -> byte[] -> string (whew!)
    ser.WriteObject(memStream, AssetsWrapper);
    byte[] AssetsWrapperByte = memStream.ToArray();
    return Encoding.UTF8.GetString(AssetsWrapperByte);
}

Solution

  • Ok, so I was able to resolve this .NET serialization weirdness by tinkering around with both the class markup as well as the actual serialization/deserialization code. Although the answers didn't work as-is, thanks to Thomas and Munim for hints that led me down the right path after some experimentation.

    Serialization changes

    Replaced DataContractSerializer with XmlSerializer. This totally sucks because it's a LOT (500%) slower :( ... (performance here)

    public string ToXmlString(OuterClass AssetsWrapper)
    {
        XmlSerializer ser = new XmlSerializer(typeof(OuterClass));            
        MemoryStream memStream = new MemoryStream();
    
        // Convert object -> stream -> byte[] -> string (whew!)
        ser.WriteObject(memStream, AssetsWrapper);
        byte[] AssetsWrapperByte = memStream.ToArray();
        return Encoding.UTF8.GetString(AssetsWrapperByte);
    }
    

    Class markup changes:

    public class OuterClass
    {
        [DataMember(Name = "Assets", Order = 10)]
        public ListAssetClass Assets { get; set; }
        ...
    
        //[DataContract(Name = "Asset123", Namespace = "")]
        public class ListAssetClass
        {
            [XmlElement(ElementName = "Asset")]
            public List<string> Assets { get; set; }
            ...
        }
    }
    

    now gives me

    <Assets>
      <Asset>Asset One</Asset>
      <Asset>Asset Two</Asset>
    </Assets>
    

    I'm surprised that the framework serialization/deserialization is so twisted and slow. I might have to look for an external library sometime.