Question
Serialize Enums as Strings in JSON with JavaScriptSerializer and .NET
Question
In .NET, how can you serialize an enum property as its string name instead of its numeric value when using JavaScriptSerializer?
For example:
enum Gender { Male, Female }
class Person
{
public int Age { get; set; }
public Gender Gender { get; set; }
}
When an instance of Person is serialized with JavaScriptSerializer, the Gender value is output as an integer. The desired JSON is:
{ "Age": 35, "Gender": "Male" }
Is there a built-in .NET Framework way to do this, such as an attribute on the enum or property, without writing a custom JavaScriptConverter? If not, what are the common alternatives, such as using Json.NET?
Short Answer
By the end of this page, you will understand why JavaScriptSerializer serializes enums as numbers, whether the .NET Framework provides a built-in attribute to change that behavior, and what practical alternatives developers use to serialize enum values as strings.
Concept
enum values in C# are named constants backed by integers. For example:
enum Gender { Male, Female }
Under the hood, Male is usually 0 and Female is 1 unless you assign different values.
When objects are converted to JSON, the serializer decides how each property should be represented. Some serializers write enum values as numbers because that is their underlying storage type. Others can write the enum member name as text.
With JavaScriptSerializer, the default behavior is to serialize enums as their numeric value, not as their name. That means:
Gender.Male
becomes:
0
not:
"Male"
This matters because string enums are often easier to read, debug, and consume across systems. For example:
- APIs are more self-descriptive with
"Male"than0 - logs and payloads are easier for humans to understand
Mental Model
Think of an enum like a labeled drawer in a cabinet.
- The label is the friendly name:
Male - The drawer number is the underlying value:
0
A serializer has to decide whether to write the label or the number.
JavaScriptSerializer chooses the drawer number by default.
If you want the label instead, you need either:
- a serializer that supports labels directly, or
- custom code that tells the serializer to use the label.
Syntax and Examples
The default JavaScriptSerializer behavior looks like this:
using System;
using System.Web.Script.Serialization;
enum Gender { Male, Female }
class Person
{
public int Age { get; set; }
public Gender Gender { get; set; }
}
class Program
{
static void Main()
{
var person = new Person
{
Age = 35,
Gender = Gender.Male
};
var serializer = new JavaScriptSerializer();
string json = serializer.Serialize(person);
Console.WriteLine(json);
}
}
Typical output:
{"Age":35,"Gender":0}
If you must stay with JavaScriptSerializer
Step by Step Execution
Consider this Json.NET example:
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public enum Gender
{
Male,
Female
}
public class Person
{
public int Age { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public Gender Gender { get; set; }
}
var person = new Person
{
Age = 35,
Gender = Gender.Male
};
string json = JsonConvert.SerializeObject(person);
Step by step:
Genderis declared as an enum.Personhas anAgeproperty and aGenderproperty.- The
Genderproperty is decorated withStringEnumConverter. - A
Personobject is created withAge = 35andGender = Gender.Male.
Real World Use Cases
Enum string serialization is common in real applications:
- Web APIs: returning
"Pending","Approved", or"Rejected"is clearer than0,1, or2 - Frontend apps: JavaScript, TypeScript, or mobile clients can display readable values more easily
- Logging and debugging: payloads are easier to inspect when enum names are visible
- Configuration files: string values are easier for humans to edit safely
- Inter-service communication: string values are more descriptive across teams and languages
Example API model:
public enum OrderStatus
{
Pending,
Paid,
Shipped,
Cancelled
}
JSON as strings:
{ "status": "Shipped" }
This is much easier to understand than:
{ "status": 2
Real Codebase Usage
In real projects, developers usually handle enum serialization in one of these ways:
1. Configure the serializer globally
This keeps behavior consistent across the whole application.
var settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter());
Useful when all API responses should use string enums.
2. Decorate only specific properties
This is helpful when only some enum fields should be strings.
[JsonConverter(typeof(StringEnumConverter))]
public Gender Gender { get; set; }
3. Use DTOs for API contracts
A domain model may use enums internally, while a DTO controls the exact JSON shape.
public class PersonDto
{
public int Age { get; set; }
public string Gender { get; set; }
}
This is common when external JSON must remain stable.
4. Validate enum values during deserialization
If strings come back from clients, developers often validate them carefully.
Common Mistakes
Assuming JavaScriptSerializer has a built-in enum string attribute
It does not provide a simple built-in attribute for this scenario.
Expecting ToString() to affect serialization automatically
This does not happen unless the serializer is explicitly told to use the string value.
Broken expectation:
public Gender Gender { get; set; }
This still becomes a number with JavaScriptSerializer.
Changing enum order later
If you serialize enums as numbers, changing the enum definition can change the meaning.
public enum Gender
{
Unknown,
Male,
Female
}
Now Male is 1 instead of 0. Old clients may misread values.
Using a string helper property but forgetting to hide the enum
You may accidentally serialize both values.
public Gender Gender { get; ; }
GenderName => Gender.ToString();
Comparisons
| Approach | Enum output | Built-in support | Best use case | Notes |
|---|---|---|---|---|
JavaScriptSerializer default | Number | Yes | Legacy .NET Framework code | No simple built-in attribute for string enums |
JavaScriptSerializer + custom JavaScriptConverter | String | Yes, but custom code required | When stuck with legacy serializer | More work to maintain |
JavaScriptSerializer + extra string property | String-like workaround | Yes | Small quick workaround | Often changes JSON shape |
Json.NET + StringEnumConverter |
Cheat Sheet
// Enum
public enum Gender
{
Male,
Female
}
JavaScriptSerializer
- Default enum output: numeric
- Example output:
{"Gender":0} - No simple built-in attribute to force enum names as strings
- To change behavior, use:
- a custom
JavaScriptConverter, or - a different serializer
- a custom
Json.NET
Property-level:
[JsonConverter(typeof(StringEnumConverter))]
public Gender Gender { get; set; }
Global:
var settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter());
Why strings are often better
- easier to read
- clearer in APIs
- less fragile if enum numeric values change
Watch out for
- changing enum member order
- accidentally serializing both enum and helper string properties
- assuming all serializers behave the same way
FAQ
Can JavaScriptSerializer serialize enums as strings by default?
No. Its default behavior is to serialize enums as numeric values.
Is there an attribute in .NET Framework for JavaScriptSerializer to output enum names?
Not a built-in one for this exact behavior. You generally need a custom JavaScriptConverter or a different serializer.
What is the easiest way to serialize enums as strings in older .NET projects?
Json.NET with StringEnumConverter is usually the easiest and most common approach.
Why do serializers often use enum numbers by default?
Because enums are backed by integers internally, and some serializers use that underlying value unless configured otherwise.
Is serializing enums as strings better for APIs?
Usually yes. String values are easier to read and less error-prone for API consumers.
Can numeric enum serialization cause problems later?
Yes. If enum ordering or assigned values change, old numeric meanings may no longer match.
What if I must keep using JavaScriptSerializer?
Your main options are writing a custom JavaScriptConverter or reshaping the serialized object to expose strings instead of raw enum properties.
Mini Project
Description
Build a small example that serializes a user profile with an enum property representing account status. First observe how the default legacy serializer outputs a number, then use Json.NET to output the enum as a readable string. This demonstrates why serializer choice matters in real API contracts.
Goal
Serialize an object containing an enum so the JSON contains the enum name as a string instead of its numeric value.
Requirements
- Create an enum named
AccountStatuswith at least three values. - Create a class with one numeric property and one enum property.
- Serialize one object and output JSON with the enum name as a string.
- Use a serializer configuration or attribute rather than manually building the JSON string.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
C# Type Checking Explained: typeof vs GetType() vs is
Learn when to use typeof, GetType(), and is in C#. Understand exact type checks, inheritance, and safe type testing clearly.
C# Version Numbers Explained: C# vs .NET Framework and Why “C# 3.5” Is Incorrect
Learn the correct C# version numbers, how they map to .NET releases, and why terms like C# 3.5 are inaccurate and confusing.