.NET XML Serialization Options.

I am creating a service that returns XML (no SOAP, no ATOM, just old old XML). Let's say I have domain objects that are already populated with data and I just need to convert them to XML format. What options do I have in .NET?

Requirements:

  • The conversion is not 1: 1. Let's say I have an Address property of type Address with nested properties like Line1, City, Postcode, etc. Perhaps this could lead to XML like <xaddr city="...">Line1, Postcode</xaddr>

    , that is, quite different.
  • Some XML elements / attributes are conditional, for example, if the client is under 18, the XML should contain some additional information.
  • I only need to serialize objects to XML, the other direction (XML for objects) is not important
  • Some technologies, i.e. Data contracts use .NET attributes. Other configuration tools (XML foreign configuration, friend classes, etc.) would be a plus.

Here are the options I see as a moment. Corrections / additions would be very welcome.

  • String concatenation - forget it, it was a joke :)
  • Linq 2 XML - Full control, but quite a lot of handwritten code, a good set of unit tests would be required
  • View engines in ASP.NET MVC (or even Web Forms in theory), logic in controllers. It's a question of how to structure it, I can have a simple rule engine in my controller and one view template per possible output, or have the decision logic directly in the template. Both have problems and disadvantages.
  • XML serialization . I'm not sure about the flexibility here.
  • Data contracts from WCF - not sure about flexibility, plus will they work in a simple ASP.NET MVC application (not for a WCF service)? Are they the superset of standard XML serialization now?
  • If it exists, some XML-to-object mapping . The more I think about it, the more I think I'm looking for something like this, but I haven't found anything suitable.

Any comments / other options?

+2


a source to share


1 answer


Xml Serialization works nicely. Attributes are used to configure it.

You can conditionally include items.

EDIT: I've updated the code to reflect your updated question.

[XmlRoot("pdata")]  // this element name used if serialized to doc root
public class PersonalData
{
     [XmlElement]  // with no name here, elt name = prop name
     public string Name;

     [XmlElement]  // with no name here, elt name = prop name
     public int Age;

     [XmlElement("xaddr")]  // override xml element name 
     public AddressData Address;

     [XmlElement] 
     public Under18Info Other {get; set;}

     // serialize the above element, only if Age < 18
     [XmlIgnore] // do not serialize the *Specified" property in any case
     private bool OtherSpecified {
        get { return Age < 18; }
     }
}

public class AddressData
{
     [XmlIgnore]   // do not serialize (see Composite prop)
     public string Line1 { get; set;}

     [XmlAttribute("city")] // serialize as an attribute on the parent 
     public string City {get; set;}

     [XmlIgnore]   // do not serialize 
     public string Postcode {get; set;}

     [XmlText]   // serialize as the Text node
     public string Composite 
     {
        get { return Line1 + ", " + Postcode; }
        set {
          var split = value.Split(',');
          Line1 = split[0];
          Postcode= split[1];
        }
     }
}

      



Then, to serialize an instance of this to a string, for example:

var pdata = new PersonalData
    {
        Name = "Gordon Brown",
        Age = 57,
        Address = new AddressData
        {
            Line1 = "10 Downing St.",
            Postcode = "1QR 3E4",
            City = "London"
        }
    };

var ns= new System.Xml.Serialization.XmlSerializerNamespaces();
ns.Add( "", "");
var s1 = new XmlSerializer(typeof(PersonalData));
var builder = new System.Text.StringBuilder();
var xmlws = new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };
using ( var writer = System.Xml.XmlWriter.Create(builder, xmlws))
{
    s1.Serialize(writer, pdata, ns);
}
string xml = builder.ToString();

      

Results:

<pdata>
  <Name>Gordon Brown</Name>
  <Age>57</Age>
  <xaddr city="London">10 Downing St., 1QR 3E4</xaddr>
</pdata>

      

+6


a source







All Articles