Enums in C# provide a structured way to represent a set of named values. However, when it comes to serialization, developers often face challenges due to varying serialization formats and requirements. In this blog post, we’ll explore the best practices for serializing enums in C#, covering JSON, XML, and custom serialization techniques.
Why Serialize Enums?
Serialization of enums is crucial when dealing with:
API responses: Enums need to be converted into string or numeric representations for easy parsing.
Configuration files: Storing and retrieving enum values from JSON or XML configurations.
Database storage: Saving enums in a way that maintains readability and compatibility.
Understanding how to serialize enums correctly ensures data integrity and smooth interoperability between different systems.
Enum Serialization in JSON
JSON serialization is a common requirement, especially when working with web APIs using ASP.NET Core. By default, System.Text.Json
serializes enums as numeric values, which may not be ideal for readability.
Using JsonStringEnumConverter
To serialize an enum as a string in JSON, use JsonStringEnumConverter
:
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
public enum OrderStatus
{
Pending,
Shipped,
Delivered,
Cancelled
}
public class Order
{
public int Id { get; set; }
public string Customer { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public OrderStatus Status { get; set; }
}
class Program
{
static void Main()
{
var order = new Order { Id = 1, Customer = "John Doe", Status = OrderStatus.Shipped };
string json = JsonSerializer.Serialize(order, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(json);
}
}
Output:
{
"Id": 1,
"Customer": "John Doe",
"Status": "Shipped"
}
This improves readability and compatibility with front-end applications consuming the API.
Enum Serialization in XML
For applications using XML serialization (e.g., WCF services), enums are serialized as strings by default.
using System;
using System.Xml.Serialization;
using System.IO;
public enum PaymentMethod
{
CreditCard,
PayPal,
BankTransfer
}
public class Transaction
{
public int TransactionId { get; set; }
[XmlElement]
public PaymentMethod Method { get; set; }
}
class Program
{
static void Main()
{
var transaction = new Transaction { TransactionId = 123, Method = PaymentMethod.PayPal };
var serializer = new XmlSerializer(typeof(Transaction));
using var writer = new StringWriter();
serializer.Serialize(writer, transaction);
Console.WriteLine(writer.ToString());
}
}
XML Output:
<Transaction>
<TransactionId>123</TransactionId>
<Method>PayPal</Method>
</Transaction>
Custom Enum Serialization
For more control over serialization, implement a custom converter.
Custom JsonConverter
for Enum Serialization
You can define a JsonConverter
to map enum values to custom strings.
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
public enum MembershipLevel
{
[EnumMember(Value = "Basic Plan")]
Basic,
[EnumMember(Value = "Premium Plan")]
Premium,
[EnumMember(Value = "VIP Plan")]
VIP
}
public class MembershipLevelConverter : JsonConverter<MembershipLevel>
{
public override MembershipLevel Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.GetString() switch
{
"Basic Plan" => MembershipLevel.Basic,
"Premium Plan" => MembershipLevel.Premium,
"VIP Plan" => MembershipLevel.VIP,
_ => throw new JsonException("Unknown membership level")
};
}
public override void Write(Utf8JsonWriter writer, MembershipLevel value, JsonSerializerOptions options)
{
string stringValue = value switch
{
MembershipLevel.Basic => "Basic Plan",
MembershipLevel.Premium => "Premium Plan",
MembershipLevel.VIP => "VIP Plan",
_ => throw new JsonException("Unknown membership level")
};
writer.WriteStringValue(stringValue);
}
}
Applying the Custom Converter:
public class User
{
public string Name { get; set; }
[JsonConverter(typeof(MembershipLevelConverter))]
public MembershipLevel Level { get; set; }
}
Output:
{
"Name": "Alice",
"Level": "Premium Plan"
}
Best Practices for Enum Serialization
1. Prefer String Representation
Using string values instead of numeric values improves readability and prevents compatibility issues when adding new enum values.
2. Use Custom Converters for Mapping
If your application requires custom names, use JsonConverter
or EnumMemberAttribute
.
3. Ensure Backward Compatibility
Avoid changing enum values drastically, as older serialized data may become invalid.
4. Handle Unknown Values Gracefully
Implement error handling when deserializing to avoid crashes due to unrecognized values.
Conclusion
Serializing enums in C# is an essential skill for API development, configuration management, and data exchange. By using JsonStringEnumConverter
, XML serialization, and custom converters, developers can achieve optimal serialization that balances readability and maintainability. Following best practices ensures robustness, backward compatibility, and a seamless developer experience.
By implementing these techniques, you can efficiently handle enum serialization in your C# applications, making your code more maintainable and API-friendly.