XML serialization options in .NET
-
25-09-2019 - |
Question
I'm building a service that returns an XML (no SOAP, no ATOM, just plain old XML). Say that I have my domain objects already filled with data and just need to transform them to the XML format. What options do I have on .NET?
Requirements:
- The transformation is not 1:1. Say that I have an Address property of type Address with nested properties like Line1, City, Postcode etc. This may need to result in an XML like
<xaddr city="...">Line1, Postcode</xaddr>
, i.e. quite different. - Some XML elements/attributes are conditional, for example, if a Customer is under 18, the XML needs to contain some additional information.
- I only need to serialize the objects to XML, the other direction (XML to objects) is not important
- Some technologies, i.e. Data Contracts use .NET attributes. Other means of configuration (external XML config, buddy classes etc.) would be a plus.
Here are the options as I see them as the moment. Corrections / additions will be very welcome.
- String concatenation - forget it, it was a joke :)
- Linq 2 XML - complete control but quite a lot of hand written code, would need good suite of unit tests
- View engines in ASP.NET MVC (or even Web Forms theoretically), the logic being in controllers. It's a question how to structure it, I can have simple rules engine in my controller(s) and one view template per each possible output, or have the decision logic directly in the template. Both have upsides and downsides.
- XML Serialization - I'm not sure about the flexibility here
- Data Contracts from WCF - not sure about the flexibility either, plus would they work in a simple ASP.NET MVC app (non-WCF service)? Are they a super-set of the standard XML serialization now?
- If it exists, some XML-to-object mapper. The more I think about it the more I think I'm looking for something like this but I couldn't find anything appropriate.
Any comments / other options?
No correct solution
OTHER TIPS
Xml Serialization works nicely. You use attributes to configure it.
You can conditionally include elements.
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 that 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>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow