MarkP
MarkP

Reputation: 4288

Serialize object to xml using PropertyInfo[] as mapping

I'm trying to write a generic method to serialize an object that inherits from my ITable interface. I would also like to have a parameter of PropertyInfo[] where I can specify the properties that need to be serialized with the object. Those that are not present are ignored. Is there a way to tell the XmlSerialize to only serialize those properties listed?

Method signature:

public static string SerializeToXml<T>(T obj, PropertyInfo[] fields = null) where T : ITable

If fields is null, Automatically grab all fields.

if (fields == null)
{
    Type type = typeof(T);
    fields = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
}

Upvotes: 1

Views: 1413

Answers (2)

svick
svick

Reputation: 244868

Normally, you would do this using attributes, specifically, you can add the [XmlIgnore] attribute to properties you don't want to serialize (notice that this is the other way around to what you want).

But since you want to do this at runtime, you can use the XmlAttributeOverrides class to, you guessed it, override the attributes at runtime.

So, something like this should work:

public static string SerializeToXml<T>(T obj, PropertyInfo[] fields = null)
    where T : ITable
{
    Type type = typeof(T);

    IEnumerable<PropertyInfo> ignoredProperties;

    if (fields == null)
        ignoredProperties = Enumerable.Empty<PropertyInfo>();
    else
        ignoredProperties = type.GetProperties(
            BindingFlags.Public | BindingFlags.Instance)
            .Except(fields);

    var ignoredAttrs = new XmlAttributes { XmlIgnore = true };

    var attrOverrides = new XmlAttributeOverrides();

    foreach (var ignoredProperty in ignoredProperties)
        attrOverrides.Add(type, ignoredProperty.Name, ignoredAttrs);

    var serializer = new XmlSerializer(type, attrOverrides);

    using (var writer = new StringWriter())
    {
        serializer.Serialize(writer, obj);
        return writer.ToString();
    }
}

On an unrelated note, I think naming a parameter that contains properties fields is highly confusing.

Upvotes: 2

Xaisoft
Xaisoft

Reputation: 46611

For each field, declare a property such as:

public bool ShouldSerializeX()
{
    return X != 0;
}

When you loop through the fields, set its property to either true or false depending on if you want to serialize it or not.

So as an example, if you have a field Address that is not present in PropertyInfo, set the property ShouldSerializeAddress to false and the XmlSerializer should ignore it.

Check this answer for more info.

Upvotes: 0

Related Questions