Shay Lugassy
Shay Lugassy

Reputation: 119

Xml Serialization using the XmlElement name of the generic type - C#

I'm trying to create a generic class that i will use for XML Serialization. The property I use to hold the generic object T is called 'Message' but I want the created XML Node of this property to be named as i notated on the class ElementType.

Example:

public class MessageWrapper<T>where T : class
{
    [XmlElement]
    public T Message { get; set; }
}

The object class i want to be held on Message property -

[XmlType("Connect"), Serializable]
public class ConnectMessage
{
    [XmlElement("Machine_Name")]
    public string MachineName { get; set; }

    [XmlElement("Application_Name")]
    public string AppName { get; set; }
}

The output XML now is this -

<Message xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Message_ID>1</Message_ID>
  <Message>
    <Machine_Name>WS-8193</Machine_Name>
    <Application_Name>TestApplication</Application_Name>
  </Message>
</Message>

Instead of this:

<Message xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Message_ID>1</Message_ID>
  <Connect>
    <Machine_Name>WS-8193</Machine_Name>
    <Application_Name>TestApplication</Application_Name>
  </Connect>
</Message>

Is that possible?

Upvotes: 0

Views: 868

Answers (1)

andrei.ciprian
andrei.ciprian

Reputation: 3025

Next to your generic approach I have a factory approach. Either way you have to rely on XmlAttributeOverrides.

public interface IMessage {}
public class AbstractMessage : IMessage { }
// your generic
public class MessageWrapper<T> where T : IMessage { public T Message { get; set; } }
// my factory
[XmlInclude(typeof(ConnectMessage))]
public class MessageWrapper { public AbstractMessage Message { get; set; } }
// overrides
public static class MessageWrapperTester {
    public static XmlAttributeOverrides XmlOverrides {
        get {
            var xmlOverrides = new XmlAttributeOverrides(); 
            var attr = new XmlAttributes();
            attr.XmlElements.Add(new XmlElementAttribute("Connect", typeof(ConnectMessage)));
            xmlOverrides.Add(typeof(MessageWrapper), "Message", attr);
            xmlOverrides.Add(typeof(MessageWrapper<>), "Message", attr);
            xmlOverrides.Add(typeof(MessageWrapper<ConnectMessage>), "Message", attr);
            return xmlOverrides;
        } } }
// use it like, generic 1st, factory 2nd:
var srlz = new XmlSerializer(typeof(MessageWrapper<ConnectMessage>), MessageWrapperTester.XmlOverrides);
var srlz = new XmlSerializer(typeof(MessageWrapper), MessageWrapperTester.XmlOverrides);

Upvotes: 1

Related Questions