NOT A DUPLICATE OF THIS: This has been flagged as a duplicate of the link that I added to an existing StackOverflow Question and Solution. This is not a duplicate as that question specifically deals with XmlElements. I am looking for a way to mould that solution to work with XmlAttributes as well as XmlElements.
I am building a Class Library that interacts with Web Service that returns XML. This Web Service is attached to a Document Management System. I have built an object for each type of entity that is in the system (Folder, Document, User, etc.). I currently have an issue where there are three different operations that return a list of documents that are in a specified directory. Each operation returns the document metadata in a different format.
<d id="1104" name="Intro.pdf" cdate="2018-06-08 13:27:05" size="188481" />
<d id="1104" n="Intro.pdf" s="188481" />
<document DocumentID="1104" Name="Intro.pdf" CreationDate="2018-06-08 13:27:05" Size="188481" />
All of these elements are for the exact same document. I am wanting to deserialise each of these into the same object called Document rather than return a different type for each item.
I found a great solution here for working with synonyms for elements. The only problem is that it does not show how I could add synonyms in for Attributes.
I have attempted to create another method that is called for the UnknownAttribute
event but I have not been successful. The method is just a copy of the SynonymHandler method in the previous link, but I have altered it slightly.
protected void AttributeSynonymHandler(object sender, XmlAttributeEventArgs e)
{
//this part works as it returns the correct property to me
var member = SynonymsAttribute.GetMember(e.ObjectBeingDeserialized, e.Attr.Name);
Type memberType;
if (member != null && member is FieldInfo)
memberType = ((FieldInfo)member).FieldType;
else if (member != null && member is PropertyInfo)
memberType = ((PropertyInfo)member).PropertyType;
else
return;
if (member != null)
{
//this is where the logic falls down, mainly because I don't have the original element anymore.
object value;
XmlSynonymDeserializer serializer = new XmlSynonymDeserializer(memberType, new XmlRootAttribute(e.Attr.Name));
using (System.IO.StringReader reader = new System.IO.StringReader(e.Attr.OuterXml))
value = serializer.Deserialize(reader);
if (member is FieldInfo)
((FieldInfo)member).SetValue(e.ObjectBeingDeserialized, value);
else if (member is PropertyInfo)
((PropertyInfo)member).SetValue(e.ObjectBeingDeserialized, value);
}
}
I am probably going about it wrong, but I was really hoping that I would be able to avoid manually handling the attributes in each case. Any help is appreciated.
EDIT: I also have the same issue when it comes to other types (e.g. Folders) so I am looking for a single solution rather than having to create a separate deserialiser for each object that this happens to. That is why I really liked the SynonymAttribute : Attribute
solution. It kept all the important information together and used Reflection to find which Attribute I was looking for.