DataContract XML serialization and XML attributes

68,230

Solution 1

This can be achieved, but you will have to override the default serializer by applying the [XmlSerializerFormat] attribute to the DataContract. Although it can be done, this does not perform as well as the default serializer, so use it with caution.

The following class structure will give you the result you are after:

using ...
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Xml.Serialization;

[DataContract]
[XmlSerializerFormat]
public class root
{
   public distance distance=new distance();
}

[DataContract]
public class distance
{
  [DataMember, XmlAttribute]
  public string units="m";

  [DataMember, XmlText]
  public int value=1000;
}

You can test this with the following code:

root mc = new root();
XmlSerializer ser = new XmlSerializer(typeof(root));
StringWriter sw = new StringWriter();
ser.Serialize(sw, mc);
Console.WriteLine(sw.ToString());
Console.ReadKey();

The output will be:

<?xml version="1.0" encoding="utf-16"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <distance units="m">1000</distance>
</root>

Solution 2

The Data Contract Serializer used by default in WCF does not support XML attributes for performance reasons (the DCS is about 10% faster on average than the XML serializer).

So if you really want to use the DCS, you cannot use this structure you have - it would have to be changed.

Or you need to use the XmlSerializer with WCF, as Greg showed in his answer - that works, too, but you lose the performance benefit (plus all other benefits) of the DCS.

Share:
68,230

Related videos on Youtube

Schultz9999
Author by

Schultz9999

Chronological development of my language skills: - Russian - Basic - Pascal - Object Pascal - Assembler - C++ - SQL - English - Java - C#, .NET - Objective C - ???

Updated on February 24, 2020

Comments

  • Schultz9999
    Schultz9999 about 4 years

    Is it possible to deserialize this XML into an object marked with the DataContract attribute?

    <root>
    <distance units="m">1000</distance>
    </root>
    

    As you may see there is "units" attribute. I don't believe that's supported. Or am I wrong?

  • jeffreypriebe
    jeffreypriebe over 12 years
    If you are looking for the XmlSerializerFormat attribute, you can find it in the System.ServiceModel namespace : msdn.microsoft.com/en-us/library/…
  • jeffreypriebe
    jeffreypriebe over 12 years
    Sure, that works for coding, I like to read the reading the docs as well :)
  • Dan Esparza
    Dan Esparza over 10 years
    @GregSansom, that assumes that you've already added the reference. Resolve doesn't appear as an option if you haven't.
  • AaronLS
    AaronLS about 10 years
    So this seems to work by using a mix of DataContract attributes and then XmlSerialization attribute XmlAttribute, which I didn't reallize you could do, I thought it was one or the other. Does the XmlSerializer ignore the DataContract attributes?
  • Sinaesthetic
    Sinaesthetic almost 8 years
    @AaronLS i just tried this and it appears to ignore the DataContact attributes. I tried to set the name [DataMember(Name = "foo")] but it was not serialized using that name, but rather the declared property name instead.
  • AaronLS
    AaronLS almost 8 years
    @Sinaesthetic Yes, so it seems if you use Data Contract Serializer, you use DataContract/Member attributes to define structure. If you use XmlSerializer, then you need to use Xml* attributes to define structure.