Question

Serialize Enums as Strings in JSON with JavaScriptSerializer and .NET

csharpasp.netjsonenumsjavascriptserializer

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" than 0
  • logs and payloads are easier for humans to understand
  • clients in other languages may not know what integer 0 means

However, not every serializer supports this automatically. In the case of JavaScriptSerializer, there is no built-in attribute that makes enum properties serialize as strings by default. If you want string output with that serializer, you typically need a custom converter or a different serializer.

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.
Take Quiz

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

There is no built-in attribute to change enum serialization to strings. Your options are usually:

  • write a custom JavaScriptConverter
  • expose a separate string property
  • switch to another serializer

A simple workaround is to serialize a string property instead of the enum directly:

using System;
using System.Web.Script.Serialization;

enum Gender { Male, Female }

class Person
{
    public int Age { get; set; }

    [ScriptIgnore]
    public Gender Gender { get; set; }

    public string GenderName
    {
        get { return Gender.ToString(); }
    }
}

This would produce JSON like:

{"Age":35,"GenderName":"Male"}

That changes the property name, so it may not match your desired contract exactly.

Using Json.NET

Json.NET supports enum string serialization cleanly.

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; }
}

Serialization:

var person = new Person { Age = 35, Gender = Gender.Male };
string json = JsonConvert.SerializeObject(person);
Console.WriteLine(json);

Output:

{"Age":35,"Gender":"Male"}

You can also apply the converter globally:

var settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter());

string json = JsonConvert.SerializeObject(person, settings);

This is a common and practical solution in real .NET projects.

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:

  1. Gender is declared as an enum.
  2. Person has an Age property and a Gender property.
  3. The Gender property is decorated with StringEnumConverter.
  4. A Person object is created with Age = 35 and Gender = Gender.Male.
  5. JsonConvert.SerializeObject(person) starts converting the object to JSON.
  6. Json.NET reads Age and writes it as 35.
  7. Json.NET reads Gender and sees the converter attribute.
  8. Instead of using the underlying integer 0, it calls the converter.
  9. The converter writes the enum name as the string "Male".
  10. The final JSON becomes:
{"Age":35,"Gender":"Male"}

If you do the same thing with JavaScriptSerializer, step 7 never happens because there is no equivalent built-in enum-as-string attribute for this case.

Real World Use Cases

Enum string serialization is common in real applications:

  • Web APIs: returning "Pending", "Approved", or "Rejected" is clearer than 0, 1, or 2
  • 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 }
Take Quiz

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.

Enum.TryParse(typeof(Gender), "Male", out var value);

5. Prefer readable contracts over implicit numeric meanings

Numeric enum values can break clients if enum order changes. String values are often safer for public APIs.

Practical note

If you are maintaining older .NET Framework code that still uses JavaScriptSerializer, many teams migrate to Json.NET or System.Text.Json in newer platforms because serializer configuration is more flexible and predictable.

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; set; }
public string GenderName => Gender.ToString();

Possible result:

{"Gender":0,"GenderName":"Male"}

If you use this workaround, hide the original property when needed.

Assuming all serializers behave the same way

Different serializers have different defaults and configuration options.

  • JavaScriptSerializer: enum as number by default
  • Json.NET: can easily use StringEnumConverter
  • System.Text.Json: can use JsonStringEnumConverter

Always check the serializer you are actually using.

Comparisons

ApproachEnum outputBuilt-in supportBest use caseNotes
JavaScriptSerializer defaultNumberYesLegacy .NET Framework codeNo simple built-in attribute for string enums
JavaScriptSerializer + custom JavaScriptConverterStringYes, but custom code requiredWhen stuck with legacy serializerMore work to maintain
JavaScriptSerializer + extra string propertyString-like workaroundYesSmall quick workaroundOften changes JSON shape
Json.NET + StringEnumConverterStringYesMost .NET Framework projectsSimple and widely used
System.Text.Json + JsonStringEnumConverterStringYesModern .NET appsNot available in older .NET Framework in the same way

Numeric enums vs string enums

FormatExampleProsCons
Number"Gender": 0Smaller payloadHarder to read, more fragile
String"Gender": "Male"Readable, safer for APIsSlightly larger payload
Take Quiz

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

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.

Take Quiz

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 AccountStatus with 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.
Take Quiz

Keep learning

Related questions

View more