JSON
deserialization
.NET
C#
k__BackingField

How to remove k__BackingField from json when Deserialize

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

The k__BackingField prefix appears in JSON output when serializing C# classes that use the [Serializable] attribute with a serializer that reads private fields instead of public properties. The compiler generates hidden backing fields like <Name>k__BackingField for auto-properties, and certain serializers expose them. The fix depends on which serializer you use: remove [Serializable], add [DataContract]/[DataMember] attributes, or configure the serializer to use property names.

Why It Happens

When you declare an auto-property in C#:

csharp
1[Serializable]
2public class User
3{
4    public string Name { get; set; }
5    public int Age { get; set; }
6}

The compiler generates hidden backing fields:

csharp
1// What the compiler actually creates:
2[Serializable]
3public class User
4{
5    [CompilerGenerated]
6    private string <Name>k__BackingField;
7
8    [CompilerGenerated]
9    private int <Age>k__BackingField;
10
11    public string Name
12    {
13        get => <Name>k__BackingField;
14        set => <Name>k__BackingField = value;
15    }
16}

When a serializer like BinaryFormatter or older JsonConvert settings reads fields (not properties), the JSON output looks like:

json
1{
2  "<Name>k__BackingField": "John",
3  "<Age>k__BackingField": 25
4}

Fix 1: Remove [Serializable] (Simplest)

If you are not using binary serialization, simply remove the [Serializable] attribute:

csharp
1// BEFORE — causes k__BackingField
2[Serializable]
3public class User
4{
5    public string Name { get; set; }
6    public int Age { get; set; }
7}
8
9// AFTER — clean JSON output
10public class User
11{
12    public string Name { get; set; }
13    public int Age { get; set; }
14}
csharp
var user = new User { Name = "John", Age = 25 };
var json = JsonSerializer.Serialize(user);
// {"Name":"John","Age":25}

Fix 2: Use [DataContract] and [DataMember]

If you need [Serializable] for other reasons, use [DataContract] to control JSON property names:

csharp
1using System.Runtime.Serialization;
2
3[Serializable]
4[DataContract]
5public class User
6{
7    [DataMember]
8    public string Name { get; set; }
9
10    [DataMember]
11    public int Age { get; set; }
12}

[DataContract] tells the serializer to use the property names (or custom names via [DataMember(Name = "...")]) instead of backing field names.

Fix 3: Newtonsoft.Json (Json.NET)

With Newtonsoft.Json, configure the contract resolver to ignore backing fields:

csharp
1using Newtonsoft.Json;
2using Newtonsoft.Json.Serialization;
3
4var settings = new JsonSerializerSettings
5{
6    ContractResolver = new DefaultContractResolver()
7};
8
9var json = JsonConvert.SerializeObject(user, settings);
10// {"Name":"John","Age":25}

Or use CamelCasePropertyNamesContractResolver for camelCase output:

csharp
1var settings = new JsonSerializerSettings
2{
3    ContractResolver = new CamelCasePropertyNamesContractResolver()
4};
5
6var json = JsonConvert.SerializeObject(user, settings);
7// {"name":"John","age":25}

You can also decorate properties with [JsonProperty]:

csharp
1[Serializable]
2public class User
3{
4    [JsonProperty("name")]
5    public string Name { get; set; }
6
7    [JsonProperty("age")]
8    public int Age { get; set; }
9}

Fix 4: System.Text.Json (.NET 6+)

System.Text.Json serializes public properties by default and does not expose backing fields:

csharp
1using System.Text.Json;
2
3[Serializable]
4public class User
5{
6    public string Name { get; set; }
7    public int Age { get; set; }
8}
9
10var user = new User { Name = "John", Age = 25 };
11var json = JsonSerializer.Serialize(user);
12// {"Name":"John","Age":25} — no k__BackingField
13
14// With camelCase naming
15var options = new JsonSerializerOptions
16{
17    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
18};
19json = JsonSerializer.Serialize(user, options);
20// {"name":"John","age":25}

System.Text.Json ignores fields by default. To include fields, you must explicitly opt in with JsonSerializerOptions.IncludeFields = true.

Fix 5: Custom Contract Resolver (Advanced)

If you need [Serializable] and cannot add [DataContract], create a custom resolver that filters out backing fields:

csharp
1using Newtonsoft.Json;
2using Newtonsoft.Json.Serialization;
3using System.Reflection;
4
5public class IgnoreBackingFieldResolver : DefaultContractResolver
6{
7    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
8    {
9        return base.GetSerializableMembers(objectType)
10            .Where(m => !m.Name.Contains("k__BackingField"))
11            .ToList();
12    }
13}
14
15var settings = new JsonSerializerSettings
16{
17    ContractResolver = new IgnoreBackingFieldResolver()
18};
19
20var json = JsonConvert.SerializeObject(user, settings);

Common Pitfalls

  • Assuming [Serializable] is needed for JSON: [Serializable] is for binary serialization (BinaryFormatter). JSON serializers like System.Text.Json and Newtonsoft.Json do not require it. Remove it unless you specifically need binary serialization.
  • Using BinaryFormatter for JSON: BinaryFormatter is insecure and deprecated in .NET 8+. If you see k__BackingField in your output, you may be using the wrong serializer entirely. Switch to System.Text.Json or Newtonsoft.Json.
  • Mixing [DataContract] and [JsonProperty]: If both attributes are present, the serializer may use one and ignore the other depending on configuration. Pick one approach and use it consistently across your model classes.
  • Forgetting [DataMember] on all properties: When [DataContract] is applied, only properties marked with [DataMember] are serialized. Unmarked properties are silently excluded from the output.
  • Deserialization fails with old JSON: If existing JSON contains k__BackingField keys and you fix the serialization, deserialization of the old data breaks. Map old field names during migration using [JsonProperty("<Name>k__BackingField")] temporarily.

Summary

  • k__BackingField appears when serializers read compiler-generated backing fields instead of public properties
  • The simplest fix is to remove [Serializable] if binary serialization is not needed
  • Use [DataContract]/[DataMember] to control serialized property names when [Serializable] is required
  • System.Text.Json ignores backing fields by default — it does not have this problem
  • Newtonsoft.Json with DefaultContractResolver also serializes properties correctly
  • Never use BinaryFormatter for JSON serialization — it is deprecated and insecure

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.