I have a weird XML setup here: I need to interface with a third-party and their XML layout that they're using is beyond my control - no chance to changing anything...
In the scope of a larger XML, I find myself needing to serialize (and later also deserialize) a list of items (for a mobile device) which are defined as having a Type and a Number property (both strings). So this would be something like:
public class SerialNumber
{
public string Type { get; set; }
public string Number { get; set; }
}
And this would normally serialize a List<SerialNumber> SerialNumbers as
<SerialNumbers>
<SerialNumber>
<Type>SN</Type>
<Number>CBS583ABC123</Number>
</SerialNumber>
<SerialNumber>
<Type>IMEI</Type>
<Number>35-924106-659945-4</Number>
</SerialNumber>
</SerialNumbers>
However, in my case, I need to send this XML:
<SerialNumbers>
<Type>SN</Type>
<Number>CBS583ABC123</Number>
<Type>IMEI</Type>
<Number>35-924106-659945-4</Number>
</SerialNumbers>
So basically, the list elements need to be omitted - I just need a container <SerialNumbers> and then for each entry in the list, I only need to serialize out the Type and Number subelements.
How can I do this easily in .NET with the XmlSerializer ?
I tried to use
[XmlRoot(ElementName="")]
public class SerialNumber
or
[XmlArray]
[XmlArrayItem(ElementName = "")]
public List<SerialNumber> SerialNumbers { get; set; }
but neither of these worked - I still get my full serialization with the <SerialNumber> elements inside the <SerialNumbers> container...
Is there an easy trick to achieve what I'm looking for? I'd much rather not go low-level and start concetanating together my XML manually....
Thanks!
You could use custom serialization with IXmlSerializable.
public class SerialNumbers : List<SerialNumber>, IXmlSerializable
{
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
Clear();
reader.ReadStartElement();
while (reader.NodeType != XmlNodeType.EndElement)
{
var serialNumber = new SerialNumber
{
Type = reader.ReadElementContentAsString("Type", ""),
Number = reader.ReadElementContentAsString("Number", "")
};
Add(serialNumber);
}
reader.ReadEndElement();
}
public void WriteXml(XmlWriter writer)
{
foreach (var serialNumber in this)
{
writer.WriteElementString("Type", serialNumber.Type);
writer.WriteElementString("Number", serialNumber.Number);
}
}
}
public class SerialNumber
{
public string Type { get; set; }
public string Number { get; set; }
}
Example:
var ser = new XmlSerializer(typeof(SerialNumbers));
var reader = new StringReader(#"
<SerialNumbers>
<Type>SN</Type>
<Number>CBS583ABC123</Number>
<Type>IMEI</Type>
<Number>35-924106-659945-4</Number>
</SerialNumbers>
".Trim());
var result = (SerialNumbers) ser.Deserialize(reader);
var writer = new StringWriter();
ser.Serialize(writer, result);
Result:
<?xml version="1.0" encoding="utf-16"?>
<SerialNumbers>
<Type>SN</Type>
<Number>CBS583ABC123</Number>
<Type>IMEI</Type>
<Number>35-924106-659945-4</Number>
</SerialNumbers>
This might do the trick for you
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class SerialNumbers
{
private string[] itemsField;
private ItemsChoiceType[] itemsElementNameField;
[System.Xml.Serialization.XmlElementAttribute("Number", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("Type", typeof(string))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
public string[] Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
[System.Xml.Serialization.XmlElementAttribute("ItemsElementName")]
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemsChoiceType[] ItemsElementName
{
get
{
return this.itemsElementNameField;
}
set
{
this.itemsElementNameField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema = false)]
public enum ItemsChoiceType
{
Number,
Type,
}
Related
I am having an issue with serializing and object, I can get it to create all the correct outputs except for where i have an Element that needs a value and an attribute. Here is the required output:
<Root>
<Method>Retrieve</Method>
<Options>
<Filter>
<Times>
<TimeFrom>2009-06-17</TimeFrom>
</Times>
<Document type="word">document name</Document>
</Filter>
</Options>
</AdCourierAPI>
I can build all of it but can not find a way to set the Document type attribute, here is a segment of the object class
[XmlRoot("Root"), Serializable]
public class Root
{
[XmlElement("Method")]
public string method="RetrieveApplications";
[XmlElement("Options")]
public _Options Options;
}
public class _Options
{
[XmlElement("Filter")]
public _Filter Filter;
}
public class _Filter
{
[XmlElement("Times")]
public _Times Times;
[XmlElement("Documents")]
public string Documents;
}
which gives me:
<Document>document name</Document>
rather than:
<Document type="word">document name</Document>
but I can not find a way to correct this, please advise.
Thanks
Where do you have the type stored?
Normally you could have something like:
class Document {
[XmlAttribute("type")]
public string Type { get; set; }
[XmlText]
public string Name { get; set; }
}
public class _Filter
{
[XmlElement("Times")]
public _Times Times;
[XmlElement("Document")]
public Document Document;
}
The string class doesn't have a type property, so you can't use it to create the desired output. You should create a Document class instead :
public class Document
{
[XmlText]
public string Name;
[XmlAttribute("type")]
public string Type;
}
And you should change the Document property to type Document
It sounds like you need an extra class:
public class Document
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlText]
public string Name { get; set; }
}
Where an instance (in the example) would have Type = "word" and Name = "document name"; documents would be a List<Document>.
By the way - public fields are rarely a good idea...
You can use XmlWriter instead XmlSerialization to get this effect.
It is more complex but if you have a lot of strings in model it will be cleaner solution.
Create your own CustomeAttribute, for example:
[System.AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class MyCustomAttribute : System.Attribute
{
public MyCustomAttribute (string type)
{
MyType = type;
}
public string MyType { get; set; }
}
Then in model add it, like that:
public class MyModel
{
[MyCustom("word")]
public string Document { get; set; }
[MyCustom("time")]
public string Time { get; set; }
}
The last part is to create xml with this arguments.
You can do it likes that:
var doc = new XmlDocument();
MyModel myModel = new MyModel();//or get it from somewhere else
using (Stream s = new MemoryStream())
{
var settings = new XmlWriterSettings();
settings.Async = true;
settings.Indent = true;
var writer = XmlTextWriter.Create(s, settings);
await writer.WriteStartDocumentAsync();
await writer.WriteStartElementAsync(null,"Root", null);
myModel.GetType().GetProperties().ToList().ForEach(async p =>
{
dynamic value = p.GetValue(myModel);
writer.WriteStartElement(p.Name);
var myCustomAttribute = p.GetCustomAttributes(typeof(MyCustomAttribute), false).FirstOrDefault() as MyCustomAttribute;
if(myCustomAttribute != null)
{
await writer.WriteAttributeStringAsync(null, "MyType", null, myCustomAttribute.MyType );
}
writer.WriteValue(value);
await writer.WriteEndElementAsync();
});
await writer.WriteEndElementAsync();
await writer.FlushAsync();
s.Position = 0;
doc.Load(s);
writer.Close();
}
string myXml = doc.OuterXml
In myXml should be something like that:
(values are examples)
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Document MyType="word">something</Document>
<Time MyType="time">11:31:29</Time>
</Root>
You can do it in other way, of course.
Here you have some docs which helped me:
https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlwriter?view=netframework-4.8#writing_elements
Is it possible to store the original XML element in a C# class, for example?
Original XML:
<data someattributea="" someattributeb="" someattributec="" />
C#
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp
{
[XmlRoot(ElementName="data")]
public class Data {
[XmlAttribute(AttributeName="someattributea")]
public string Someattributea { get; set; }
[XmlAttribute(AttributeName="someattributeb")]
public string Someattributeb { get; set; }
[XmlAttribute(AttributeName="someattributec")]
public string Someattributec { get; set; }
public sourceXML { get; set; } //this would return <data someattributea="" someattributeb="" someattributec="" />
}
}
I understand I could deserialize the class again but some XML objects are unknown at design time.
If you really need to capture everything about the <data /> element including the element name and namespace itself into a string literal, you will need to implement IXmlSerializable and serialize your Data type manually. For instance, here is a prototype implementation:
[XmlRoot(ElementName = ElementName)]
public class Data : IXmlSerializable
{
public const string ElementName = "data";
XElement element = new XElement((XName)ElementName);
public string Someattributea
{
get { return (string)element.Attribute("someattributea"); }
set { element.SetAttribute("someattributea", value); }
}
public string Someattributeb
{
get { return (string)element.Attribute("someattributeb"); }
set { element.SetAttribute("someattributeb", value); }
}
public string Someattributec
{
get { return (string)element.Attribute("someattributec"); }
set { element.SetAttribute("someattributec", value); }
}
public string SourceXML
{
get
{
return element.ToString();
}
set
{
if (value == null)
throw new ArgumentNullException();
element = XElement.Parse(value);
}
}
#region IXmlSerializable Members
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader)
{
reader.MoveToContent();
element = (XElement)XNode.ReadFrom(reader);
}
public void WriteXml(XmlWriter writer)
{
foreach (var attr in element.Attributes())
writer.WriteAttributeString(attr.Name.LocalName, attr.Name.NamespaceName, attr.Value);
foreach (var child in element.Elements())
child.WriteTo(writer);
}
#endregion
}
public static class XElementExtensions
{
public static void SetAttribute(this XElement element, XName attributeName, string value)
{
var attr = element.Attribute(attributeName);
if (value == null)
{
if (attr != null)
attr.Remove();
}
else
{
if (attr == null)
element.Add(new XAttribute(attributeName, value));
else
attr.Value = value;
}
}
}
Notes:
When reading, the complete XML is loaded into an XElement member which can be queried using LINQ to XML. As a result the original formatting may get lost.
IXmlSerializable is tricky to implement correctly. See Proper way to implement IXmlSerializable? and How to Implement IXmlSerializable Correctly for some tips on how to do it.
The known properties Someattributea, Someattributeb and Someattributec now become surrogate lookups into the underlying XElement.
Working .Net fiddle here.
If, on the other hand, you only need to capture unknown elements, attributes and text content, you can use [XmlAnyAttribute], [XmlAnyElement] and [XmlText] (the first two of which are suggested in this answer to XmlSerializer equivalent of IExtensibleDataObject by Marc Gravell). This approach results in a much simpler version of Data:
[XmlRoot(ElementName = "data")]
public class Data
{
[XmlAttribute(AttributeName = "someattributea")]
public string Someattributea { get; set; }
[XmlAttribute(AttributeName = "someattributeb")]
public string Someattributeb { get; set; }
[XmlAttribute(AttributeName = "someattributec")]
public string Someattributec { get; set; }
[XmlAnyAttribute]
public XmlAttribute[] Attributes { get; set; }
[XmlAnyElement]
[XmlText] // Captures mixed content at the root level as well as child elements.
public XmlNode[] ChildNodes { get; set; }
}
Working .Net fiddle #2 here.
I have two classes, "company" derived from Treenode, and "document".
[Serializable]
[XmlRoot("Company")]
public class Company : TreeNode, IXmlSerializable
{
private string _x;
private string _y;
public Company() { }
[XmlElement("X")]
public string X { get; set; }
[XmlElement("Y")]
public string Y { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "Company")
{
x = reader["X"].ToString;
y = reader["Y"].ToString;
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteElementString("X", this.X.ToString());
writer.WriteElementString("Y", this.Y.ToString());
}
}
public class Document
{
private int _id;
private string _name;
private Company _company;
public Document() { }
[XmlElement("ID")]
public int ID { get; set; }
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("Company")]
public Company Comp { get; set; }
}
When I try to serialize document, then save to file, its work. But when I deserialize, reader parameter always null. Any solutions ?
This is my code for deserialize. "sr" is variable that hold xml text.
var sr = new StreamReader(ms);
var myStr = sr.ReadToEnd();
XmlSerializer serializer = new XmlSerializer(typeof(List<Document>));
using (TextReader tr = new StringReader(myStr))
{
List<Document> docu = (List<Document>)serializer.Deserialize(tr);
}
I try to implement ISerialization and debug but never fired, and try to overide serialize and deserialize method, and no luck.
I am using .NET Framework 3.5
As explained in this article, implementing IXmlSerializable correctly is in fact quite tricky. Your implementation of ReadXml() appears to violate the requirement that it consume the wrapper element itself as well as all the contents, like so:
public void ReadXml(System.Xml.XmlReader reader)
{
reader.MoveToContent();
// Read attributes
Boolean isEmptyElement = reader.IsEmptyElement; // (1)
reader.ReadStartElement();
if (!isEmptyElement) // (1)
{
// Read Child elements X and Y
// Consume the end of the wrapper element
reader.ReadEndElement();
}
}
Furthermore, reader["X"] returns the value of the XML attribute named "X", as explained in the docs. In your WriteXml() you wrote the values of X and Y as nested XML elements. This explains the NullReferenceException. You need to fix your read and write methods to be consistent.
However, I'd suggest an alternative to implementing IXmlSerializable, which is to introduce a surrogate type for your Company. First, extract all the non-TreeNode properties of Company into an interface:
public interface ICompany
{
string X { get; set; }
string Y { get; set; }
}
public class Company : TreeNode, ICompany
{
public Company() { }
public string X { get; set; }
public string Y { get; set; }
}
This is optional but makes the code clearer. Next, introduce a surrogate POCO that implements the same interface but does not inherit from TreeNode:
public class CompanySurrogate : ICompany
{
public string X { get; set; }
public string Y { get; set; }
public static implicit operator CompanySurrogate(Company company)
{
if (company == null)
return null;
// For more complex types, use AutoMapper
return new CompanySurrogate { X = company.X, Y = company.Y };
}
public static implicit operator Company(CompanySurrogate surrogate)
{
if (surrogate == null)
return null;
// For more complex types, use AutoMapper
return new Company { X = surrogate.X, Y = surrogate.Y };
}
}
Notice that the surrogate can be implicitly converted to your original Company type? Now you can use the surrogate in XML serialization by setting the XmlElementAttribute.Type attribute property to be that of the surrogate:
public class Document
{
public Document() { }
[XmlElement("ID")]
public int ID { get; set; }
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("Company", Type = typeof(CompanySurrogate))]
public Company Comp { get; set; }
}
This avoids all possibilities of error in implementing IXmlSerializable. Given the following input list:
var list = new List<Document>
{
new Document { Name = "my name", ID = 101, Comp = new Company { X = "foo", Y = "bar", NodeFont = new System.Drawing.Font("Arial", 10) } },
new Document { Name = "2nd name", ID = 222, Comp = new Company { X = "tlon", Y = "ukbar" } },
};
The following XML can will be generated, and can be deserialized successfully:
<ArrayOfDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Document>
<ID>101</ID>
<Name>my name</Name>
<Company>
<X>foo</X>
<Y>bar</Y>
</Company>
</Document>
<Document>
<ID>222</ID>
<Name>2nd name</Name>
<Company>
<X>tlon</X>
<Y>ukbar</Y>
</Company>
</Document>
</ArrayOfDocument>
That being said, I don't really recommend this design. Your UI should present your data model, it should not be your data model. See for instance How does one implement UI independent applications?. Replacing Company with ICompany whenever possible could be a first step to changing your design; you may find it becomes easier to replace your existing architecture with a TreeNode that looks like this:
public class CompanyNode : TreeNode
{
public ICompany Company { get; set; }
}
I have xml like this:
<data>
<audit_values>
<audit_value>
<channel>2</channel>
<week>
<mo_th>6,501698000000</mo_th>
<fr>8,414278000000</fr>
<sa>9,292674000000</sa>
<sun>8,551982000000</sun>
<holid>7,164605000000</holid>
</week>
</audit_value>
<audit_value>
<channel>1</channel>
<week>
<mo_th>6,501698000000</mo_th>
<fr>8,414278000000</fr>
<sa>9,292674000000</sa>
<sun>8,551982000000</sun>
<holid>7,164605000000</holid>
</week>
</audit_value>
</audit_values>
</data>
And I need to deserialize it to class. But the problem is, that week will be change in future(it will be contains more elements, and name of them I dont know)
Data:
[XmlRoot("data")]
public class Data
{
[XmlArray("audit_values")]
[XmlArrayItem("audit_value", IsNullable = true)]
public AuditValue[] AuditValues { get; set; }
}
AuditValue:
[XmlRoot("audit_value")]
public class AuditValue
{
[XmlElement("week", typeof(TVR))]
public Week Week;
}
Week:
[XmlRoot("week")]
public class Week : IXmlSerializable
{
public Dictionary<string, double> Values = new Dictionary<string, double>();
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
reader.Read();
var sub = reader.ReadSubtree();
do
{
if (sub.NodeType == XmlNodeType.Element)
{
string name = sub.Name;
string val = sub.ReadElementContentAsString();
Values.Add(name, Convert.ToDouble(val));
}
} while (sub.Read());
}
public void WriteXml(XmlWriter writer)
{
}
}
But after deserialization I have only one element with only one recored in dictionary Values. What I'm doing wrong?
GitHub:
https://github.com/olegletynain/XmlTest/tree/master/XmlTestRead
I tweaked your ReadXml method based on #Matthew Whited's idea in the comments section and the following method does the job:
public void ReadXml(XmlReader reader)
{
Values = XElement.Parse(reader.ReadOuterXml())
.Elements()
.ToDictionary(k => k.Name.ToString(), v => double.Parse(v.Value));
}
As a side note you only need XmlRoot on the actual root element not on every class so I removed it from AuditValue and Week. Also I don't know what TVR is. It didn't compile with "typeof(TVR)" so I removed it as well.
For the sake of completeness here's my version of the classes:
[XmlRoot("data")]
public class Data
{
[XmlArray("audit_values")]
[XmlArrayItem("audit_value", IsNullable = true)]
public AuditValue[] AuditValues { get; set; }
}
public class AuditValue
{
[XmlElement("week")]
public Week Week;
}
public class Week : IXmlSerializable
{
public Dictionary<string, double> Values = new Dictionary<string, double>();
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
Values = XElement.Parse(reader.ReadOuterXml())
.Elements()
.ToDictionary(k => k.Name.ToString(), v => double.Parse(v.Value));
}
public void WriteXml(XmlWriter writer)
{
}
}
You should consider using the DataContractSerializer instead of XmlSerializer and implement the IExtensibleDataObject interface on your DataContract class.
Implementing IExtensibleDataObject allows the DataContract class to persist unknown information in the ExtensionData field, which prevents it from being lost if the XML being deserialized contains unknown elements, and then is re-serialized and saved.
Your Audit class would look something like this:
[DataContract(Name = "audit_value", Namespace = "")]
public class AuditValue : IExtensibleDataObject
{
[DataMember(Name = "channel")]
public int Channel { get; set; }
[DataMember(Name = "week")]
public Week Week { get; set; }
public ExtensionDataObject ExtensionData { get; set; }
}
[DataContract(Name = "week", Namespace = "")]
public class Week : IExtensibleDataObject
{
[DataMember(Name = "mo_th")]
public Decimal MondayThroughThursday { get; set; }
public ExtensionDataObject ExtensionData { get; set; }
}
You'll still need to update your code to deserialize the additional elements as POCOs, but at least the underlying data will be persisted until you get around to it.
Try this. XmlElement eliminates a lay of tags which you don't have. You have an extra 's' at end of values.
From
[XmlArray("audit_values")]
[XmlArrayItem("audit_value", IsNullable = true)]
public AuditValue[] AuditValues { get; set; }
To
[XmlElement("audit_value")]
public AuditValue[] AuditValues { get; set; }
The error was in ReadXml method, now I changed it to this:
public void ReadXml(XmlReader reader)
{
reader.Read();
do
{
if (!reader.IsEmptyElement)
{
var name = reader.Name;
var val = Convert.ToDouble(reader.ReadElementContentAsString());
Values.Add(name, val);
}
else
{
reader.Skip();
}
} while (reader.Name != "week");
if (reader.NodeType == XmlNodeType.EndElement)
{
reader.ReadEndElement();
}
}
And I works fine. This Solution without using XElement and Linq, #Volkan Paksoy offered method with XElement which is easier to understand
I'm trying to find out a solution for this, but I'm not sure if it's possible or not.
I have a base class, lets say
public class A
{
[XmlAttribute("Date")]
public DateTime Date {get;set;}
}
and a derived class:
public class B: A
{
[XmlAttribute("Date")]
public new String StringDate {get;set;}
}
I have to serialize a Xml.
The value of "Date" on the Xml, is String and in fact it's not a DateTime format string. But I use "A" for many other stuff so I cannot just change it to String without affecting other parts of the program. Sadly it is not an option.
So my idea is to create a derived class "B" who inherit everything of "A" and overrided the property Date to get it fill from the deserialization and then format it to DateTime.
I read about virtual or abstracts but I'm not acquainted with it and don't have any clue about it, if it is the solution maybe someone can guide me on the first steps.
Anyone can help me?
EDIT
XML:
<Vorgang Vorgang="HQHT8GTQ">
<Vertragsbeginn Vertragsbeginn="20140202" />
</Vorgang>
Class A:
[DataContract(Name = "Vorgang")]
[KnownType(typeof(Vorgang))]
public class Vorgang
{
[IgnoreDataMember]
public DateTime Vertragsbeginn { get; set; }
}
Class B:
public class VorgangOverride : UTILMD.Vorgang
{
private string datestring;
[XmlAttribute("Vertragsbeginn")]
public new String Vertragsbeginn {
get { return datestring; }
set
{
base.Vertragsbeginn = DateUtil.StringToDate(value, EDIEnums.Vertragsbeginn);
datestring = value;
}
}
}
Deserialization method:
private static VorgangOverride Deserialize (XmlNode inVorgang)
{
using (MemoryStream stm = new MemoryStream())
{
using (StreamWriter stw = new StreamWriter(stm))
{
stw.Write(inVorgang.OuterXml);
stw.Flush();
stm.Position = 0;
XmlRootAttribute xRoot = new XmlRootAttribute { ElementName = "Vorgang", IsNullable = true };
var serializer = new XmlSerializer(typeof(VorgangOverride), xRoot);
VorgangOverride podItem = (VorgangOverride) serializer.Deserialize(stm);
return podItem;
}
}
}
EDIT:
Solved using
[XmlRoot("Vorgang")]
public class VorgangOverride
{
public VorgangOverride()
{
}
#region Public Properties
public string datestring;
[XmlElement("Vertragsbeginn")]
public Vertragsbeginn VertragsbeginnAsString { get ; set ;}
#endregion
}
public class Vertragsbeginn
{
[XmlAttribute("Vertragsbeginn")]
public String vertragsbeginn { get; set; }
}
I found the solution:
[DataContract(Name = "Vorgang")]
[KnownType(typeof(Vorgang))]
public class Vorgang
{
[XmlIgnore] // use XmlIgnore instead IgnoreDataMember
public DateTime Vertragsbeginn { get; set; }
}
// this class map all elements from the xml that you show
[XmlRoot("Vorgang")] // to map the Xml Vorgang as a VorgangOverride instance
public class VorgangOverride : Vorgang
{
[XmlAttribute("Vorgang2")] // to map the Vorgang attribute
public string VorgangAttribute { get; set; }
[XmlElement(ElementName = "Vertragsbeginn")] // to map the Vertragsbeginn element
public Vertragsbeginn VertragsbeginnElement
{
get { return _vertragsbeginn; }
set
{
base.Vertragsbeginn = new DateTime(); // here I Assing the correct value to the DateTime property on Vorgan class.
_vertragsbeginn = value;
}
}
private Vertragsbeginn _vertragsbeginn;
}
// this class is used to map the Vertragsbeginn element
public class Vertragsbeginn
{
[XmlAttribute("Vertragsbeginn")] // to map the Vertragsbeginn attriubute on the Vertragsbeginn element
public string VertragsbeginnAttribute { get; set; }
}
later I say:
var string xmlContent =
#"<Vorgang Vorgang2=""HQHT8GTQ"">
<Vertragsbeginn Vertragsbeginn=""20140202"" />
</Vorgang>";
var a = Deserialize<VorgangOverride>(xmlContent);
and this is the method to Deserialize:
// method used to deserialize an xml to object
public static T Deserialize<T>(string xmlContent)
{
T result;
var xmlSerializer = new XmlSerializer(typeof(T));
using (TextReader textReader = new StringReader(xmlContent))
{
result = ((T)xmlSerializer.Deserialize(textReader));
}
return result;
}
You will not be able to override a property with an other class type.
The reason is Polymorphism. (more information: https://msdn.microsoft.com/en-us/library/ms173152.aspx)
You can cast the class B to class A. Which means the class B must have all the properties and methods class A has, too. But in your case class B would have a String rather than a Date called Date. Which is simply not possible.