69

In C#, how can I make XmlSerializer ignore a property during serialization but not during deserialization? (Or how do I do the same with Json.net?)

To prevent a property from being serialized, you can add the XmlIgnore attribute:

[XmlIgnore]
public int FooBar {get;set;}

This will cause the <FooBar> tag to be omitted during serialization.

However, this also means that the <FooBar> tag will be ignored during deserialization.

In my case, I accept an array of items from user in the request, and for each item user can specify an action property if they want to add, modify or delete the item. I want to use the same model object for GET list calls, and don't want to return this action property. I expect this would be a pretty common case.

Another use case: say you have a circle object

public class Circle
{
    public double Radius { get; set; }
}

and you modify it to add a diameter property

public class Circle2
{
    public double Diameter { get; set; }
    public double Radius { get { return Diameter / 2; } set { Diameter = value*2; } }
}

You may want to serialize only the diameter, but still be able to deserialize xml files in the old format that contain only the radius.

I did my research and didn't find anything, hence this question

Solution: I figured out the solution. I can add a ShouldSerialize property which always return false, details at this MSDN documentation

(this solution could be added as an actual answer if this question is reopened)

Johannes Rabauer
  • 330
  • 3
  • 15
Manoj
  • 1,005
  • 1
  • 9
  • 11
  • How can you not serialize it but then expect it to deserialize it? – Justin Aug 14 '13 at 21:08
  • Give a property a default value?.. How else would you "not ignore" a property during deserialization? – Sergey Kalinichenko Aug 14 '13 at 21:08
  • I'm too lazy to search the docs right now but if you look through json.NET's documentation I guarantee it has examples that show you how to ignore a property during serialization/deserialization. – evanmcdonnal Aug 14 '13 at 21:09
  • What do you expect from us? do the research for you? write the code? we all here have plenty of time to do your work... – I4V Aug 14 '13 at 21:16
  • 2
    It's easy to ignore a property for both serialization and deserialization, you can specify XmlIgnoreAttribute for that. In my case, I accept an array of items from user in the request, and for each item user can specify an action property if they want to add, modify or delete the item. I want to use the same model object for GET list calls, and don't want to return this action property. I expect this would be a pretty common case. I did my research and didn't find anything, hence this question. – Manoj Aug 15 '13 at 00:23
  • 10
    What a bunch of halfassed responses. Shame on you guys. In my case, I want to stop serializing a property because it has been moved to a different class, but if it has already been serialized, it still needs to be deserialized. If I were to use XmlIgnore it would no longer be deserialized and the data would be lost. – xr280xr Oct 21 '13 at 18:32
  • 5
    I vote to reopen this question. It is a quite useful question, and the solution the original author added at the end is the correct solution. Seems like a shame that the correct answer cannot be added as an actual answer since the question is closed. – HugoRune Mar 05 '14 at 09:47

2 Answers2

49

This is the solution outlined by Manoj:

If you want to suppress serialization of a specific property Foo, but still be able to deserialize it, you can add a method public bool ShouldSerializeFoo() that always returns false.

Example:

public class Circle2
{
    public double Diameter { get; set; }
    public double Radius { get { return Diameter / 2; } set { Diameter = value*2; } }

    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public bool ShouldSerializeRadius() {return false;}
}

This will cause the Radius to not be serialized, but still allow it to be deserialized.

This method has to be public for the XMLSerializer to find it, so in order to avoid polluting the namespace you can add the EditorBrowsable attribute to hide it from the IDE. Unfortunately this hiding only works if the assembly is referenced as a DLL in your current project, but not if you edit the actual project with this code.

HugoRune
  • 13,157
  • 7
  • 69
  • 144
46

If you want to ignore the element at serialization with XmlSerializer, you can use XmlAttributeOverrides:

XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = true;
attribs.XmlElements.Add(new XmlElementAttribute("YourElementName"));
overrides.Add(typeof(YourClass), "YourElementName", attribs);

XmlSerializer ser = new XmlSerializer(typeof(YourClass), overrides);
ser.Serialize(...
fcuesta
  • 4,429
  • 1
  • 18
  • 13
  • Thank you Fcuesta, But XmlIgnore would apply to both serialization and deserialization. I am looking for a way to be able to deserialize if the property is provided, but never serialize it. – Manoj Aug 15 '13 at 00:29
  • 8
    When serializing use: XmlSerializer ser = new XmlSerializer(typeof(YourClass), overrides); when deserializing use XmlSerializer ser = new XmlSerializer(typeof(YourClass)); without the overrides parameter – fcuesta Aug 15 '13 at 00:30
  • Thanks you. This mechanism is not very intuitive. – xr280xr Oct 21 '13 at 18:34
  • I have another problem. What if the property that I want to ignore is property of a class whose object is a property of the main class? For example, I want to ignore property of a city class but objCity is object of class State that I am serializing. :( – Dhanashree Jan 17 '17 at 15:35
  • 2
    A serializer constructed using overrides should be statically cached to avoid a memory leak; see [Memory Leak using StreamReader and XmlSerializer](https://stackoverflow.com/q/23897145/3744182) for details. – dbc Mar 07 '18 at 19:13