44

I recently upgraded a solution to be all .NET Core 3 and I have a class that requires the class variables to be fields. This is a problem since the new System.Text.Json.JsonSerializer doesn't support serializing nor deserializing fields but only handles properties instead.

Is there any way to ensure that the two final classes in the example below have the same exact values?

using System.Text.Json;

public class Car
{
    public int Year { get; set; } // does serialize correctly
    public string Model; // doesn't serialize correctly
}

static void Problem() {
    Car car = new Car()
    {
        Model = "Fit",
        Year = 2008,
    };
    string json = JsonSerializer.Serialize(car); // {"Year":2008}
    Car carDeserialized = JsonSerializer.Deserialize<Car>(json);

    Console.WriteLine(carDeserialized.Model); // null!
}
dbc
  • 104,963
  • 20
  • 228
  • 340
BillHaggerty
  • 6,157
  • 10
  • 35
  • 68

3 Answers3

54

In .NET Core 3.x, System.Text.Json does not serialize fields. From the docs:

Fields are not supported in System.Text.Json in .NET Core 3.1. Custom converters can provide this functionality.

In .NET 5 and later, public fields can be serialized by setting JsonSerializerOptions.IncludeFields to true or by marking the field to serialize with [JsonInclude]:

using System.Text.Json;

static void Main()
{
    var car = new Car { Model = "Fit", Year = 2008 };

    // Enable support
    var options = new JsonSerializerOptions { IncludeFields = true };

    // Pass "options"
    var json = JsonSerializer.Serialize(car, options);

    // Pass "options"
    var carDeserialized = JsonSerializer.Deserialize<Car>(json, options);

    Console.WriteLine(carDeserialized.Model); // Writes "Fit"
}

public class Car
{
    public int Year { get; set; }
    public string Model;
}

For details see:

dbc
  • 104,963
  • 20
  • 228
  • 340
pavinan
  • 1,275
  • 1
  • 12
  • 23
  • 4
    Also documented in [How to serialize and deserialize JSON in .NET: Serialization behavior](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to#serialization-behavior): *By default, all public properties are serialized. You can specify properties to exclude... Currently, fields are excluded.* – dbc Nov 10 '19 at 03:46
  • 1
    I edited the answer now that it's possible (in pre-release version). – Vimes Sep 22 '20 at 21:16
  • 2
    You can use Sytem.Text.Json >=5.0.2 package in .net core 3.1 – tymtam Apr 23 '21 at 03:29
3

If you want this for all MvcControllers in API project you can do similar to this in setup:

builder.Services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.IncludeFields = true;
});
NiKiZe
  • 1,256
  • 10
  • 26
-1

Please try this library I wrote as an extension to System.Text.Json to offer missing features: https://github.com/dahomey-technologies/Dahomey.Json.

You will find support for fields.

using System.Text.Json;
using Dahomey.Json

public class Car
{
    public int Year { get; set; } // does serialize correctly
    public string Model; // will serialize correctly
}

static void Problem() {
    JsonSerializerOptions options = new JsonSerializerOptions();
    options.SetupExtensions(); // extension method to setup Dahomey.Json extensions

    Car car = new Car()
    {
        Model = "Fit",
        Year = 2008,
    };
    string json = JsonSerializer.Serialize(car, options); // {"Year":2008,"Model":"Fit"}
    Car carDeserialized = JsonSerializer.Deserialize<Car>(json);

    Console.WriteLine(carDeserialized.Model); // Fit
}