3

Is it possible to control XmlSerializer/DataContractSerializer behavior without specifying any serialization attributes?

To be more specific, I want to control the serialization (XmlIgnore, custom attribute name etc.), but without decorating my properties. Use cases:

  • A large existing class, which I don't wish to pollute with serialization attributes
  • Serializing a class for which no source code is available
  • Switching from using XmlSerializer to DataContractSerializer to JSON without changing class code

For example, how would I serialize the following without uncommenting the attributes:

// [Serializable]
public MyClass
{
    // [XmlIgnore] - The following property should not be serialized, without uncommenting this line
    public int DontSerializeMeEvenThoughImPublic { get; set; }

    // [XmlAttribute("another_name")] - should be serialized as 'another_name', not 'SerializeMeAsXmlAttribute'
    public double SerializeMeAsXmlAttribute { get; set; }

    // [DataMember] - should be included
    private string IWantToBeSerializedButDontDecorateMeWithDataMember { get; set; }
}
5
  • Have you tried to serialize without attributes? Commented Sep 15, 2014 at 12:26
  • 1
    You should be able to serialise fine without attributes, you just cannot control the output. Commented Sep 15, 2014 at 12:29
  • Should it obey the uncommented attributes in your sample? If not, please remove them. Commented Sep 15, 2014 at 12:31
  • @BenRobinson - that is untrue. For example, DontSerializeMeEvenThoughImPublic would be serialized even though it should be ignored Commented Sep 15, 2014 at 12:34
  • @bavaza, as I said "you cannot control the output". Commented Sep 15, 2014 at 12:43

3 Answers 3

5

You can't (do it elegantly).
The only way to modify the way the XmlSerializer serializes classes is by using attributes (by the way SerializableAttribute is not required). The DataContractSerializer is even worse.

One possible solution is to create intermediate classes for XML serialization/desrialization and use Automapper to copy the data between the "real" class and mediator. I've used this approach to keep the front end XML serialization concerns outside of my business logic data types.

Sign up to request clarification or add additional context in comments.

1 Comment

big big like for suggesting Automapper. A great library :-)
4

I know this is an old question, but for the XmlSerializer part, it's interesting that no one has suggested the use of Attribute overrides.

Although not solving the Private property, but AFAIK you can't do that with attributes either, so the only route there would be the IXmlSerializable interface.

But what you can do by adding Attributes should be possible with overrides as well.

The following should work for the change wishes reflected by the outcommented XmlAttributes:

public class Program
{
    public static void Main()
    {
        XmlAttributeOverrides overrides = new XmlAttributeOverrides();
        overrides.Add(typeof(MyClass), "DontSerializeMeEvenThoughImPublic", new XmlAttributes { XmlIgnore = true });
        overrides.Add(typeof(MyClass), "SerializeMeAsXmlAttribute", new XmlAttributes { XmlAttribute = new XmlAttributeAttribute("another_name") });
        XmlSerializer serializer = new XmlSerializer(typeof(MyClass), overrides);
        using (var writer = new StringWriter())
        {
            serializer.Serialize(writer, new MyClass());
            Console.WriteLine(writer.ToString());
        }
    }
}

1 Comment

This is what I was looking for. IMHO It should be the serializer's job to handle serialization, the data structure itself shouldnt know about a string/XML representation of the data.
2

Serialization via XmlSerializer should work without the attributes.

5 Comments

How would you ignore the first property in the question without attributes?
I guess this would be impossible without the attributes. On the other hand, would it hurt? Your possibilities are a bit limited if you cannot change the class in question. It depends a bit on the overall goal.
I will not be able to control the serialization. For example, DontSerializeMeEvenThoughImPublic would be serialized even though it should be ignored.
One possibility would be to have an adapter class which has the same data members and can be assigned from/to the previously existing type. However, this approach is not very elegant and would tend to be hard to maintain.
@PatrickHofman You would use XmlAttributeOverrides, they won't solve the Private property though AFAIK...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.