Datacontract Xml Serialization and Xml Attributes

DataContract XML serialization and XML attributes

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>

How can you control .NET DataContract serialization so it uses XML attributes instead of elements?

You can't do this with the DataContractSerializer; if you want attributes you need to use the XmlSerializer instead. With the DataContractSerializer class a more restrictive subset of the XML specification is permitted which improves performance, and improves the interoperability of published services, but gives you rather less control over the XML format.

If you're using WCF services then take a look at XmlSerializerFormatAttribute which allows you to use the XmlSerializer for serialization.

How do I add an XML attribute using DataContract

You can't add attributes to a DataContract. You either have to use a class that Implements ISerializable or use the .Net XmlSerializer.

How to deserialize XML attribute using DataContract in Windows Phone 7

Repeated question. How can you control .NET DataContract serialization so it uses XML attributes instead of elements? You can't do that with a DataContractSerializer, but you should achieve what you ask for using the XmlSerializer.

Web API 2 XML Serialization and DataContracts

You need to declare Type_X and Type_Y as the known types:

[DataContract]
[KnownType(typeof(Type_X))]
[KnownType(typeof(Type_Y))]
public abstract class BaseClass
{
[DataMember]
public Dictionary<string, object> BaseDictionary { get; set; }

public BaseClass()
{
BaseDictionary = new Dictionary<string, object>();
}
}

What you did is to declare Dictionary<string, Type_X> as a known type, however that type isn't encountered in the object graph. Rather, you need to declare the actual types that will appear as dictionary values, since those cannot be inferred statically.

Having done so, the data contract serializer will generate XML that looks something like:

<ConcreteClass xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Question41066771">
<BaseDictionary xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>X</d2p1:Key>
<d2p1:Value i:type="Type_X">
<X>x</X>
</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>Y</d2p1:Key>
<d2p1:Value i:type="Type_Y">
<Y>y</Y>
</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
</BaseDictionary>
</ConcreteClass>

Given the concrete classes:

[DataContract]
public class ConcreteClass : BaseClass
{
}

[DataContract]
public class Type_X
{
[DataMember]
public string X { get; set; }
}

[DataContract]
public class Type_Y
{
[DataMember]
public string Y { get; set; }
}

The i:type attribute is a w3c standard attribute that allows an element to assert its type. The data contract serializer uses it to indicate the actual contract name of the polymorphic type being serialized. For more, see Data Contract Known Types.

DataContract deserialize XML - List of elements and properties in the same element

Try this... (uses XmlSerializer rather than DataContractSerializer)

Usings...

using System;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.IO;

Classes...(created from your XML using http://xmltocsharp.azurewebsites.net/)

[XmlRoot(ElementName = "FlightSegment")]
public class FlightSegment
{
[XmlElement(ElementName = "DepDate")]
public string DepDate { get; set; }
[XmlElement(ElementName = "DepTime")]
public string DepTime { get; set; }
[XmlElement(ElementName = "ArrDate")]
public string ArrDate { get; set; }
[XmlElement(ElementName = "ArrTime")]
public string ArrTime { get; set; }
[XmlElement(ElementName = "DepDay")]
public string DepDay { get; set; }
[XmlElement(ElementName = "ArrDay")]
public string ArrDay { get; set; }
[XmlElement(ElementName = "DepAirport")]
public string DepAirport { get; set; }
[XmlElement(ElementName = "DepAirportName")]
public string DepAirportName { get; set; }
[XmlElement(ElementName = "DepCityName")]
public string DepCityName { get; set; }
[XmlElement(ElementName = "ArrAirport")]
public string ArrAirport { get; set; }
[XmlElement(ElementName = "ArrAirportName")]
public string ArrAirportName { get; set; }
[XmlElement(ElementName = "ArrCityName")]
public string ArrCityName { get; set; }
[XmlElement(ElementName = "DepCountry")]
public string DepCountry { get; set; }
[XmlElement(ElementName = "ArrCountry")]
public string ArrCountry { get; set; }
[XmlElement(ElementName = "Airline")]
public string Airline { get; set; }
[XmlElement(ElementName = "AirName")]
public string AirName { get; set; }
[XmlElement(ElementName = "FlightNo")]
public string FlightNo { get; set; }
[XmlElement(ElementName = "BookingClass")]
public string BookingClass { get; set; }
[XmlElement(ElementName = "AirCraftType")]
public string AirCraftType { get; set; }
[XmlElement(ElementName = "ETicket")]
public string ETicket { get; set; }
[XmlElement(ElementName = "NonStop")]
public string NonStop { get; set; }
[XmlElement(ElementName = "DepTer")]
public string DepTer { get; set; }
[XmlElement(ElementName = "ArrTer")]
public string ArrTer { get; set; }
[XmlElement(ElementName = "AdtFareBasis")]
public string AdtFareBasis { get; set; }
[XmlElement(ElementName = "ChdFareBasis")]
public string ChdFareBasis { get; set; }
[XmlElement(ElementName = "InfFareBasis")]
public string InfFareBasis { get; set; }
}

[XmlRoot(ElementName = "RecommendedSegment")]
public class RecommendedSegment
{
[XmlElement(ElementName = "Duration")]
public string Duration { get; set; }
[XmlElement(ElementName = "FareBasis")]
public string FareBasis { get; set; }
[XmlElement(ElementName = "FlightSegment")]
public List<FlightSegment> FlightSegment { get; set; }
[XmlElement(ElementName = "DepAirport")]
public string DepAirport { get; set; }
[XmlElement(ElementName = "DepCity")]
public string DepCity { get; set; }
[XmlElement(ElementName = "DepCountry")]
public string DepCountry { get; set; }
[XmlElement(ElementName = "DepZone")]
public string DepZone { get; set; }
[XmlElement(ElementName = "ArrAirport")]
public string ArrAirport { get; set; }
[XmlElement(ElementName = "ArrCity")]
public string ArrCity { get; set; }
[XmlElement(ElementName = "ArrCountry")]
public string ArrCountry { get; set; }
[XmlElement(ElementName = "ArrZone")]
public string ArrZone { get; set; }
}

[XmlRoot(ElementName = "Availability")]
public class Availability
{
[XmlElement(ElementName = "RecommendedSegment")]
public RecommendedSegment RecommendedSegment { get; set; }
}

Code....

        try
{
Availability deserializedXML = new Availability();
// Deserialize to object
XmlSerializer serializer = new XmlSerializer(typeof(Availability));
using (FileStream stream = File.OpenRead(@"xml.xml"))
{
deserializedXML = (Availability)serializer.Deserialize(stream);
} // Put a break-point here, then mouse-over deserializedXML
}
catch (Exception)
{

throw;
}

Save your XML to a file (xml.xml) in the same folder as your .EXE.... Hope that helps.

XMLAttribute equivalent for DataContractSerialization?

<System.Xml.Serialization.XmlAttribute()>

Should solve your problem, for more information see MSDN XmlAttribute reference.



Related Topics



Leave a reply



Submit