XML Attribute on Plain String - c#

I'd like to generate some XML like the following with C# code.
<card>
<name>Cool Card</name>
<set rarity="common">S1</set>
</card>
I have something like this.
public class card
{
public string name = "Cool Card";
[XmlAttribute]
public string rarity = "common";
public string set = "S1";
}
public static void WriteXml()
{
var serializer = new XmlSerializer(typeof(card));
var myCard = new();
using var sw = new StringWriter();
serializer.Serialize(sw, myCard);
XDocument doc = XDocument.Parse(sw.ToString());
XmlWriterSettings xws = new();
xws.OmitXmlDeclaration = true;
xws.Indent = true;
using var xw = XmlWriter.Create(path, xws);
doc.Save(xw);
}
The problem is that this doesn't add the "rarity" attribute to the "set" value. Trying to add [XmlAttribute] adds it to the parent element rather than the next sibling element and I can't figure out how to get it on a plain string element, so at present my output looks like.
<card rarity="common">
<name>Cool Card</name>
<set>S1</set>
</card>
The XML example doc shows an example of how to set the attribute on an element, but only one with nested fields and not one that's a plain string. Is it possible to add an attribute to a plain old string element in XML like my first posted example demonstrates?

Try this:
public class card
{
public string name = "Cool Card";
public Set set = new();
}
public class Set
{
[XmlText]
public string value = "S1";
[XmlAttribute]
public string rarity = "common";
}
If you think about it there is no other way the xml attribute can be applied only to the element it is declared in. So you need to move it into another class. When you do this new property for value is required and that one needs to be flattened as value node is not required for that you need XmlText attribute.

The cleanest option in this case is implement IXmlSerializable:
public class card : IXmlSerializable
{
public string name = "Cool Card";
public string rarity = "common";
public string set = "S1";
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
reader.ReadStartElement(nameof(card));
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
if (reader.Name == nameof(name))
{
this.name = reader.ReadElementContentAsString();
}
else if (reader.Name == nameof(set))
{
this.rarity = reader.GetAttribute(nameof(rarity));
this.set = reader.ReadElementContentAsString();
}
}
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteElementString(nameof(name), this.name);
writer.WriteStartElement(nameof(set));
writer.WriteAttributeString(nameof(rarity), this.rarity);
writer.WriteString(this.set);
writer.WriteEndElement();
}
}
If your class is big and you only need do a bit change in the XML, sometimes implement IXmlSerializable is a mess (you must save all the properties and only in one or two, do a bit change). In these cases, you can use attributes and some small helpers classes to get same results. The idea is tell to XML serializer that don't serialize some property and use another fake property to do the serialization.
For example, create a Set class with your desired XML structure:
public class XmlSet
{
private readonly card _card;
public XmlSet()
{
this._card = new card();
}
public XmlSet(card card)
{
this._card = card;
}
[XmlText]
public string set
{
get { return this._card.set; }
set { this._card.set = value; }
}
[XmlAttribute]
public string rarity
{
get { return this._card.rarity; }
set { this._card.rarity = value; }
}
}
It's only a wrapper, with the XML sttributes that you want. You get/set the values from/to your card object.
Then, in your card class, Ignore the set property and serialize the fake property:
public class card
{
public string name = "Cool Card";
[XmlIgnore]
public string rarity = "common";
[XmlIgnore]
public string set = "S1";
// Added to serialization
private XmlSet _xmlSetNode;
[XmlElement("set")]
public XmlSet XmlSet
{
get
{
this._xmlSetNode = this._xmlSetNode ?? new XmlSet(this);
return this._xmlSetNode;
}
set { this._xmlSetNode = value; }
}
}

Related

How to deserialize a JSON array to a List using System.Runtime.Serialization.Json

I am trying to deserialize a JSON file but for some reason, I just can't seem to get it to work. Is this the correct way to deserialize a JSON array to a list.
This is the JSON Data I would like to deserialize and put into the coursework object
{
"assignments":[
{
"categoryname":"Exams",
"description":"Test covers C#, classes and other topics",
"name":"Exam 1"
},
{
"categoryname":"Exams",
"description":"Test covers collections and other topics",
"name":"Exam 2"
},
Deserialization Method I am using
List<T> ReadJsonFile1<T>(List<T> obj)
{
Console.Write("Enter Json File Name: ");
string fileName = Console.ReadLine();
FileStream reader = new FileStream(fileName, FileMode.Open, FileAccess.Read);
DataContractJsonSerializer deser;
deser = new DataContractJsonSerializer(typeof(List<T>));
obj = (List<T>)deser.ReadObject(reader);
reader.Close();
return obj;
}
Code I execute in Main
CourseWork cw = new CourseWork();
cw.Assignment = ReadJsonFile1<Assignment>(cw.Assignment);
CourseWork Class
public class CourseWork
{
private List<Assignment> assignments;
[DataMember(Name = "assignmentname")]
public List<Assignment> Assignment
{
get { return assignments; }
set { assignments = value; }
}
public CourseWork()
{
assignments = new List<Assignment>();
}
Assignment Class
private string name;
private string description;
private string categoryName;
//DataContract
[DataMember(Name = "name")]
public string Name
{
get { return name; }
set { name = value; }
}
//DataContract
[DataMember(Name = "description")]
public string Description
{
get { return description; }
set { description = value; }
}
//DataContract
[DataMember(Name = "categoryname")]
public string CategoryName
{
get { return categoryName; }
set { categoryName = value; }
}
public Assignment()
{
name = "defaut";
description = "defaut";
categoryName = "defaut";
}
1
I don't know this deserialiser well but
deser = new DataContractJsonSerializer(typeof(List<T>));
Should likely be something like
deser = new DataContractJsonSerializer(typeof(CourseWork));
2
[DataMember(Name = "assignmentname")]
public List<Assignment> Assignment
quite likely should be
[DataMember(Name = "assignments")]
public List<Assignment> Assignment
{
What I did not take into consideration is that CourseWork is not a list, it just has lists inside it as private member variables. To fix my problem I had to change my List<T> ReadJsonFile1<T>(List<T> obj) function back to what I had it earlier in the project T ReadJsonFile1<T>(T obj) Basically just taking all the Lists out and making them normal type of T. I also needed to add DataContract Names to ALL my classes. My DataMembers were fine but since this is a Json Array I needed to add the DataContract above every class like in the Assignment class and also the CourseWork Class, just need to make sure you give your DataContract the correct name.
SOLUTION
List<T> ReadJsonFile1<T>(List<T> obj)
[DataContract(Name = "coursename")]
public class CourseWork
{
[DataContract(Name = "assignments")]
public class Assignment
{

Creating and using custom XML special characters with XmlSerializer

I have a ColorFormat class that stores basic information about a color format. The aim is to be able to serialize and deserialize to and from XML. To represent Red, Green and Blue I use special color string identifiers:
public const string RedColorIdentifier = "&red;";
public const string GreenColorIdentifier = "&green;";
public const string BlueColorIdentifier = "&blue;";
For a format like "#RGB", the class format string is as such:
colorFormat.Format = "#" + ColorFormat.RedColorIdentifier +
ColorFormat.GreenColorIdentifier +
ColorFormat.BlueColorIdentifier;
Ideally, the serialized XML should be:
<ColorFormat Name="HexFmt" ColorBase="Hex">#&red;&green;&blue;</ColorFormat>
The actual serialization is:
<ColorFormat Name="HexFmt" ColorBase="Hex">#&red;&green;&blue;</ColorFormat>
I was wondering if there is a way of "serializing and deserializing" your own custom special XML character
You can use CData to wrap special characters.
From MSDN CDATA Section
For example class below will be serialized witt color values wrapped with CData
[XmlType("ColorFormat")]
public class ColorFormat
{
[XmlAttribute]
public string Name { get; set; }
[XmlAttribute]
public string ColorBase { get; set; }
[XmlIgnore]
public string Format { get; set; }
[XmlText]
public XmlNode[] SerializableFormat
{
get
{
var doc = new XmlDocument();
return new XmlNode[] { doc.CreateCDataSection(this.Format) };
}
set
{
this.Format = value[0].Value;
}
}
}
Using of ColorFormat class
const string FORMAT = "&red;&green;&blue;";
var format = new ColorFormat
{
Name = "HexFormat",
ColorBase = "Hex",
Format = FORMAT
};
var serializer = new XmlSerializer(typeof(ColorFormat));
using (var writer = new StringWriter())
{
serializer.Serialize(writer, format);
Console.WriteLine(writer.ToString());
}
Finally found it, gotta implement IXmlSerializable as such:
public class ColorFormat : IXmlSerializable
{
...
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
Name = reader.GetAttribute(nameof(Name));
ColorBase = CommonUtil.ParseStringToEnum<NumberBase>(reader.GetAttribute(nameof(ColorBase)));
Format = reader.ReadInnerXml();
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString(nameof(Name), Name);
writer.WriteAttributeString(nameof(ColorBase), ColorBase.ToString());
writer.WriteRaw(Format);
}
}

Changing type of element in XML Serialization

I am having huge problems with XML serialization. I have two classes, both need to be serializeable. In the inherited class, I would like to change the serialization behavior, so that a string property gets serialized as complex type.
public class Animal
{
[XmlElement(ElementName = "NAME")]
public string Name { get; set; }
public virtual bool ShouldSerializeName() { return true; }
}
public class Cat : Animal
{
public override bool ShouldSerializeName() { return false; }
[XmlElement(ElementName = "NAME")]
public NameAndType Name2 { get; set; }
}
public class NameAndType
{
public string Name { get; set; }
public string Type { get; set; }
}
...
var cat = new Cat {Name2 = new NameAndType {Name = "LittleCat"}};
new XmlSerializer(typeof(Cat)).Serialize(Console.Out, cat);
I have tried different approaches, but I didn't find a way to change how the NAME element get's serialized.
With the example above, I get the error message:
The XML element 'NAME' from namespace '' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.
The reason you get the error is that, during XmlSerializer code generation, the code generator doesn't understand that the two potential NAME elements on Cat will never be simultaneously serialized, so throws the exception.
Instead, you can apply XmlAnyElementAttribute to a virtual property returning an XElement, then manually create and return an appropriate XElement for the name for each class in the hierarchy:
[XmlInclude(typeof(Cat))]
public class Animal
{
[XmlIgnore]
public string Name { get; set; }
[XmlAnyElement]
public virtual XElement XmlName
{
get
{
return Name == null ? null : new XElement("NAME", Name);
}
set
{
Name = (value == null ? null : value.Value);
}
}
}
public class Cat : Animal
{
// Must be cached as per https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer%28v=vs.110%29.aspx
static XmlSerializer nameSerializer;
static Cat()
{
nameSerializer = new XmlSerializer(typeof(NameAndType), new XmlRootAttribute("NAME"));
}
[XmlIgnore]
public NameAndType Name2 { get; set; }
[XmlAnyElement]
public override XElement XmlName
{
get
{
return (Name2 == null ? null : XObjectExtensions.SerializeToXElement(Name2, nameSerializer, true));
}
set
{
Name2 = (value == null ? null : XObjectExtensions.Deserialize<NameAndType>(value, nameSerializer));
}
}
}
Using the extension methods:
public static class XObjectExtensions
{
public static T Deserialize<T>(this XContainer element)
{
return element.Deserialize<T>(new XmlSerializer(typeof(T)));
}
public static T Deserialize<T>(this XContainer element, XmlSerializer serializer)
{
using (var reader = element.CreateReader())
{
object result = serializer.Deserialize(reader);
if (result is T)
return (T)result;
}
return default(T);
}
public static XElement SerializeToXElement<T>(this T obj)
{
return obj.SerializeToXElement(new XmlSerializer(obj.GetType()), true);
}
public static XElement SerializeToXElement<T>(this T obj, XmlSerializer serializer, bool omitStandardNamespaces)
{
var doc = new XDocument();
using (var writer = doc.CreateWriter())
{
XmlSerializerNamespaces ns = null;
if (omitStandardNamespaces)
(ns = new XmlSerializerNamespaces()).Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
serializer.Serialize(writer, obj, ns);
}
var element = doc.Root;
if (element != null)
element.Remove();
return element;
}
}
Which, for a List<Animal>, produces XML like this:
<ArrayOfAnimal xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Animal>
<NAME>duck</NAME>
</Animal>
<Animal xsi:type="Cat">
<NAME>
<Name>Smokey</Name>
<Type>Siamese</Type>
</NAME>
</Animal>
</ArrayOfAnimal>
You're specifying two different XML elements with the same name on the same graph level, which is not allowed.
I will offer a solution, but it involves concatenating type and name for the Cat class serialization. If it is not imperative to serialize that NameAndType class, then go on:
On Animal, set Name to be virtual;
On Cat, set XmlIgnore on Name2. Then override Name and return both properties of Name2 the way you fancy.
If you really need to serialize that class as it is, then I'm afraid you'll have to so it with a different elementName.
Edit: Sample code:
public class Animal
{
[XmlElement(ElementName = "NAME")]
public virtual string Name { get; set; }
public virtual bool ShouldSerializeName() { return true; }
}
public class Cat : Animal
{
public override bool ShouldSerializeName() { return false; }
[XmlIgnore]
public NameAndType Name2 { get; set; }
[XmlElement(ElementName = "NAME")]
public override string Name
{
get
{
return String.Format("{0} [Type:{1}]", Name2.Name, Name2.Type);
}
set { }
}
}

How to serialize List<IFilter> (Nokia Imaging SDK)?

I'm trying to save a List of IFilter(of type Interface) which are applied to an image using XML serialization, so that user can edit the same image from where he left off.
[XmlRoot]
public class ImageProperties
{
public string ImageName { get; set; }
public string ImageFilePath { get; set; }
public List<IFilter> Filters { get; set; }
}
Is this possible? Is there another alternative to do the same?
You could use IXmlSerializable to achieve this.. assuming you can change the ImageProperties class.
Upon serialization, you can get the type by looking at each filter instance and querying for it. You can store this type information in the XML so when you come to read it, you know which type it is, and you can then just invoke the default XML serializer for each filter.
Here is a possible implementation.
public class ImageProperties : IXmlSerializable
{
public string ImageName { get; set; }
public string ImageFilePath { get; set; }
public List<IFilter> Filters { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
string startEle = reader.Name;
reader.ReadStartElement();
Filters = new List<IFilter>();
do
{
switch (reader.Name)
{
case "imgName":
ImageName = reader.ReadElementContentAsString();
break;
case "imgFilePath":
ImageFilePath = reader.ReadElementContentAsString();
break;
case "filters":
reader.ReadStartElement("filters");
while (reader.Name.Equals("iFilter"))
{
XmlSerializer filterSerializer = new XmlSerializer(Type.GetType(reader.GetAttribute("type")));
reader.ReadStartElement("iFilter");
Filters.Add((IFilter)filterSerializer.Deserialize(reader));
reader.ReadEndElement();
}
reader.ReadEndElement();
break;
default:
reader.ReadOuterXml();
break;
}
} while (reader.Name != startEle);
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteElementString("imgName", ImageName);
writer.WriteElementString("imgFilePath", ImageFilePath);
writer.WriteStartElement("filters");
foreach (IFilter filter in Filters)
{
writer.WriteStartElement("iFilter");
writer.WriteAttributeString("type", filter.GetType().FullName);
XmlSerializer filterSerializer = new XmlSerializer(filter.GetType());
filterSerializer.Serialize(writer, filter);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
}
If you have different types of filter, the default serializer of the real type is invoked, so their unique properties will get recorded.
For example, with these filter classes available:
public interface IFilter
{
string SomeCommonProp { get; set;}
}
[XmlRoot("myFilter")]
public class MyFilter : IFilter
{
[XmlElement("somemyFilterProp")]
public string SomeMyFilterProp { get; set; }
[XmlElement("someCommonProp")]
public string SomeCommonProp { get; set;}
}
[XmlRoot("myOtherFilter")]
public class MyOtherFilter : IFilter
{
[XmlElement("someOtherFilterProp")]
public string SomeOtherFilterProp { get; set; }
[XmlElement("someCommonProp")]
public string SomeCommonProp { get; set;}
}
You can use as follows to serialise and deserialise two different types of filter in IFilters to xml.
static void Main(string[] args)
{
ImageProperties props = new ImageProperties();
props.ImageName = "img.png";
props.ImageFilePath = "c:\\temp\\img.png";
props.Filters = new List<IFilter>();
props.Filters.Add(new MyFilter() { SomeMyFilterProp = "x", SomeCommonProp ="p" });
props.Filters.Add(new MyOtherFilter() { SomeOtherFilterProp = "y", SomeCommonProp ="p" });
XmlSerializer s = new XmlSerializer(typeof(ImageProperties));
using (StreamWriter writer = new StreamWriter(#"c:\temp\imgprops.xml"))
s.Serialize(writer, props);
using (StreamReader reader = new StreamReader(#"c:\temp\imgprops.xml"))
{
object andBack = s.Deserialize(reader);
}
Console.ReadKey();
}
This produces an XML that looks like this.
<?xml version="1.0" encoding="utf-8"?>
<ImageProperties>
<imgName>img.png</imgName>
<imgFilePath>c:\temp\img.png</imgFilePath>
<filters>
<iFilter type="SomeNameSpace.Whatever.MyFilter">
<myFilter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<somemyFilterProp>x</somemyFilterProp>
<someCommonProp>p</someCommonProp>
</myFilter>
</iFilter>
<iFilter type="SomeNameSpace.Whatever.MyOtherFilter">
<myOtherFilter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<someOtherFilterProp>y</someOtherFilterProp>
<someCommonProp>p</someCommonProp>
</myOtherFilter>
</iFilter>
</filters>
</ImageProperties>
No. Interface instances cannot be serialized. It doesn't know the implementation to "deserialize" to. It will require a concrete class or custom serialization in this case.

Problem with serializing a dictionary wrapper

I defined two classes. First one...
[Serializable]
public class LocalizationEntry
{
public LocalizationEntry()
{
this.CatalogName = string.Empty;
this.Identifier = string.Empty;
this.Translation = new Dictionary<string, string>();
this.TranslationsList = new List<Translation>();
}
public string CatalogName
{
get;
set;
}
public string Identifier
{
get;
set;
}
[XmlIgnore]
public Dictionary<string, string> Translation
{
get;
set;
}
[XmlArray(ElementName = "Translations")]
public List<Translation> TranslationsList
{
get
{
var list = new List<Translation>();
foreach (var item in this.Translation)
{
list.Add(new Translation(item.Key, item.Value));
}
return list;
}
set
{
foreach (var item in value)
{
this.Translation.Add(item.Language, item.Text);
}
}
}
}
...where public List<Translation> TranslationsList is a wrapper for non-serializable public Dictionary<string, string> Translation.
Pair of key and value is defined as follows:
[Serializable]
public class Translation
{
[XmlAttribute(AttributeName = "lang")]
public string Language
{
get;
set;
}
[XmlText]
public string Text
{
get;
set;
}
public Translation()
{
}
public Translation(string language, string translation)
{
this.Language = language;
this.Text = translation;
}
}
At last code used to serialize:
static void Main(string[] args)
{
LocalizationEntry entry = new LocalizationEntry()
{
CatalogName = "Catalog",
Identifier = "Id",
};
entry.Translation.Add("PL", "jabłko");
entry.Translation.Add("EN", "apple");
entry.Translation.Add("DE", "apfel");
using (FileStream stream = File.Open(#"C:\entry.xml", FileMode.Create))
{
XmlSerializer serializer = new XmlSerializer(typeof(LocalizationEntry));
serializer.Serialize(stream, entry);
}
LocalizationEntry deserializedEntry;
using (FileStream stream = File.Open(#"C:\entry.xml", FileMode.Open))
{
XmlSerializer serializer = new XmlSerializer(typeof(LocalizationEntry));
deserializedEntry = (LocalizationEntry)serializer.Deserialize(stream);
}
}
The problem is that after deserialization deserializedEntry.TranslationsList is empty. I set a breakpoint at setter of LocalizationEntry.TransalionsList and it comes from deserializer empty as well. Product of serialization is of course valid. Is there any gap in my code?
EDIT:
Here is generated XML:
<?xml version="1.0"?>
<LocalizationEntry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CatalogName>Catalog</CatalogName>
<Identifier>Id</Identifier>
<Translations>
<Translation lang="PL">jabłko</Translation>
<Translation lang="EN">apple</Translation>
<Translation lang="DE">apfel</Translation>
</Translations>
</LocalizationEntry>
The problem is that your TranslationList property is not being set by the Xml Deserializer. The set method will be hit but only by the call to this.TranslationsList = new List(); in the LocalisationEntry constructor. I'm not yet sure why but I suspect it's because it doesn't know how to convert an array of Translation objects back into a List.
I added the following code and it worked fine:
[XmlArray(ElementName = "Translations")]
public Translation[] TranslationArray
{
get
{
return TranslationsList.ToArray();
}
set
{
TranslationsList = new List<Translation>(value);
}
}
[XmlIgnore]
public List<Translation> TranslationsList
....
I am guessing the problem has to do with this:
public List<Translation> TranslationsList
The get/set operators are designed only for something to get or assign a fully-formed list. If you tried to use this in your own code, for example, every time you would do something like
TranslationsList.Add(item)
It would just create a new list from the existing dictionary and not actually deal with your item. I bet the deserializer works much the same way: uses set to create the new object once, then uses get as it adds each item from the XML. Since all that happens in get is it copies from the dictionary (which is empty when you begin your deserialization) you end up with nothing.
Try replacing this with just a field:
public List<Translation> TranslationsList;
and then explicitly call the code to copy the dictionary to this list before you serialize, and copy it from this list to the dictionary after you deserialize. Assuming that works, you can probably figure out a more seamless way to implement what you're trying to do.
I've created a sample, which will allow you to avoid the unnecessary hidden property when using the XmlSerializer:
class Program
{
static void Main(string[] args)
{
LocalizationEntry entry = new LocalizationEntry()
{
CatalogName = "Catalog",
Identifier = "Id",
Translations =
{
{ "PL", "jabłko" },
{ "EN", "apple" },
{ "DE", "apfel" }
}
};
using (MemoryStream stream = new MemoryStream())
{
XmlSerializer serializer = new XmlSerializer(typeof(LocalizationEntry));
serializer.Serialize(stream, entry);
stream.Seek(0, SeekOrigin.Begin);
LocalizationEntry deserializedEntry = (LocalizationEntry)serializer.Deserialize(stream);
serializer.Serialize(Console.Out, deserializedEntry);
}
}
}
public class LocalizationEntry
{
public LocalizationEntry() { this.Translations = new TranslationCollection(); }
public string CatalogName { get; set; }
public string Identifier { get; set; }
[XmlArrayItem]
public TranslationCollection Translations { get; private set; }
}
public class TranslationCollection
: Collection<Translation>
{
public TranslationCollection(params Translation[] items)
{
if (null != items)
{
foreach (Translation item in items)
{
this.Add(item);
}
}
}
public void Add(string language, string text)
{
this.Add(new Translation
{
Language = language,
Text = text
});
}
}
public class Translation
{
[XmlAttribute(AttributeName = "lang")]
public string Language { get; set; }
[XmlText]
public string Text { get; set; }
}
There are some drawbacks when working with the XmlSerializer class itself. The .NET guidelines encourage you the not provide public-setters for collection-properties (like your translation list). But when you look at the code generated by the XmlSerializer, you'll see that it will use the Setter regardless of it is accessible. This results in a compile-error when the interim class is dynamically loaded by the XmlSerializer. The only way to avoid this, is to make the XmlSerializer think, that it can't actually create an instance of the list and thus won't try to call set for it. If the XmlSerializer detects that it can't create an instance it will throw an exception instead of using the Setter and the interim class is compiled successfully. I've used the param-keyword to trick the serializer into thinking that there is no default-constructor.
The only drawback from this solution is that you have to use a non-generic, non-interface type for the property (TranslationCollection) in my example.

Categories

Resources