XML
Serialization
Deserialization
C#
Data Processing

Ignore a property during xml serialization but not during deserialization

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

With XmlSerializer, [XmlIgnore] removes a property from both serialization and deserialization, so it is not the right tool when you want one-way behavior. If the goal is to skip writing a property to XML while still accepting it when XML contains that element, the usual fix is conditional serialization, most commonly through a ShouldSerializePropertyName() method.

Why [XmlIgnore] Is Not Enough

This attribute blocks both directions:

csharp
1using System.Xml.Serialization;
2
3public class Order
4{
5    [XmlIgnore]
6    public string InternalCode { get; set; } = "";
7}

That means:

  • the property is not written during serialization
  • the property is also ignored during deserialization

So if an incoming XML document contains <InternalCode>ABC</InternalCode>, XmlSerializer will not populate the property.

Use ShouldSerialize... to Skip Writing Only

XmlSerializer supports a convention-based method named ShouldSerializePropertyName(). If that method returns false, the property is omitted from serialized output, but it still remains a normal deserialization target.

csharp
1using System;
2using System.IO;
3using System.Xml.Serialization;
4
5public class Order
6{
7    public string CustomerName { get; set; } = "";
8    public string InternalCode { get; set; } = "";
9
10    public bool ShouldSerializeInternalCode()
11    {
12        return false;
13    }
14}
15
16var serializer = new XmlSerializer(typeof(Order));
17
18var order = new Order
19{
20    CustomerName = "Ava",
21    InternalCode = "SECRET-42"
22};
23
24using var writer = new StringWriter();
25serializer.Serialize(writer, order);
26Console.WriteLine(writer.ToString());

The generated XML contains CustomerName but not InternalCode.

Deserialization Still Works

Because InternalCode is still a normal serializable property, deserialization can populate it when the XML includes that element.

csharp
1using System;
2using System.IO;
3using System.Xml.Serialization;
4
5string xml = """
6<Order>
7  <CustomerName>Ava</CustomerName>
8  <InternalCode>FROM-XML</InternalCode>
9</Order>
10""";
11
12var serializer = new XmlSerializer(typeof(Order));
13using var reader = new StringReader(xml);
14var order = (Order)serializer.Deserialize(reader)!;
15
16Console.WriteLine(order.CustomerName);
17Console.WriteLine(order.InternalCode);

This is the key trick: the property is skipped on output but still accepted on input.

When a Surrogate Property Is Better

Sometimes the XML shape needs to differ from the in-memory property shape. In that case, a surrogate property can be cleaner than relying on ShouldSerialize.

csharp
1using System.Xml.Serialization;
2
3public class UserRecord
4{
5    [XmlIgnore]
6    public string SecretToken { get; set; } = "";
7
8    [XmlElement("SecretToken")]
9    public string SecretTokenXml
10    {
11        get => SecretToken;
12        set => SecretToken = value;
13    }
14
15    public bool ShouldSerializeSecretTokenXml()
16    {
17        return false;
18    }
19}

This is more verbose, but it gives you a dedicated XML-facing surface if the serialization contract needs extra control.

Know the Limits of XmlSerializer

XmlSerializer is heavily convention-based. That is powerful once you know the conventions, but it also means the behavior can feel surprising if you expect attribute-driven one-way control for every case.

If your requirements are very custom, alternatives such as manual XML handling or a different serializer may be easier to reason about than piling more conventions onto one type.

Common Pitfalls

The most common mistake is applying [XmlIgnore] and expecting the property to deserialize anyway. It will not.

Another mistake is naming the helper method incorrectly. The serializer looks for the exact ShouldSerializePropertyName pattern, so the method name has to match the property name precisely.

Developers also sometimes use one-way serialization logic for security but forget that deserialized values are still untrusted input. If the property matters to business logic, validate it after deserialization.

Finally, if the XML contract and the object model are drifting apart, that is a sign to consider a dedicated DTO instead of making one class satisfy every scenario.

Summary

  • '[XmlIgnore] disables both XML serialization and deserialization for a property.'
  • Use ShouldSerializePropertyName() when you want to skip serialization only.
  • The property can still be populated during deserialization if the XML contains it.
  • A surrogate XML-facing property is useful when the contract needs more control.
  • Validate deserialized values even if you intentionally hide the property on output.

Course illustration
Course illustration

All Rights Reserved.