gordieb
gordieb

Reputation: 251

How to serialize non-property members in .net core 3.1?

We just migrated our web api projects from .net core 2.2 to 3.1. Today we run into an unexpected issue where public class members are not being serialize to JSON.

Example:

class MyClass {
    public int mA;
    public int pA {get; set;}
}

 [...]

// and then in a controller:
return Ok(new MyClass {
    mA = 1,
    pA = 2
});

The JSON object received is as follows:

{
    "pA":2
}

The serialization used to work in .net core 2.2 that used Newtonsoft.

Is there a way to configure System.Text.Json to support serialization of non-property members?

Upvotes: 1

Views: 1210

Answers (2)

Rena
Rena

Reputation: 36705

What @NAS did support in asp.net 5.0 instead of asp.net core 3.1.The document below clearly points that you could use the JsonSerializerOptions.IncludeFields global setting or the [JsonInclude] attribute to include fields when serializing or deserializing.

Reference:

https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to?pivots=dotnet-5-0#include-fields

I think a simple way is to migrate to asp.net 5,and choose each of the two ways above.

For asp.net core 3.1,it does not support Fields,you could check the docs,

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

public class FieldConverter
    : JsonConverter<MyClass>
{
    public override void Write(Utf8JsonWriter writer,
                       MyClass value,
                       JsonSerializerOptions options)
    {
        //serialize to json
        writer.WriteStartObject();

        writer.WriteNumber("mA", value.mA);
        writer.WriteNumber("pA", value.pA);
        writer.WriteEndObject();
    }
    public override MyClass Read(ref Utf8JsonReader reader,
                             Type typeToConvert,
                             JsonSerializerOptions options)
    {
         //deserialize to model...
        var model = new MyClass();
        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.PropertyName)
            {
                string propertyName = reader.GetString();
                reader.Read();
                switch (propertyName)
                {
                    case "mA":
                        int ma = reader.GetInt32();
                        model.mA = ma;
                        break;
                    case "pA":
                        int pa = reader.GetInt32();
                        model.pA = pa;
                        break;                        
                }
            }
        }

        return model;
    }
}

Model:

[JsonConverter(typeof(FieldConverter))]
public class MyClass
{
    public int mA;
    public int pA { get; set; }

}

Reference:

https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-core-3-1

Upvotes: 2

NAS
NAS

Reputation: 331

you can enable fields support like this

var jsonSerializerOptions = new JsonSerializerOptions { IncludeFields = true };

This will enable globally in Startup.cs as

services.AddControllers()
                .AddJsonOptions(options => 
                {
                    options.JsonSerializerOptions.IncludeFields = true;


                });

Upvotes: 2

Related Questions