JamesNK / Newtonsoft.Json

Json.NET is a popular high-performance JSON framework for .NET
https://www.newtonsoft.com/json
MIT License
10.65k stars 3.24k forks source link

JRaw returns an empty array when upgrading to .net core 3.0 #2281

Open hasithapg opened 4 years ago

hasithapg commented 4 years ago

Source/destination types

public class EndPoint 
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public JRaw Definition { get; set; }

    }

Source/destination JSON

{"message":"[{"Id":"AA0D2668-1C3D-4432-B4A0-1DC2BA9F84A3","Name":"ManagementQueue","Definition":{ 
        "ConnectionString" : "Server=\\XXXXXX;Database=XXXXX;User Id=XXXXXXX;Password=XXXXXXXXXXXX;"}}]"}

Expected behavior

[
  {
    "id": "aa0d2668-1c3d-4432-b4a0-1dc2ba9f84a3",
    "name": "ManagementQueue",

    "definition": { 
        "ConnectionString" : "Server=\\XXXXXX;Database=XXXXX;User Id=XXXXXXX;Password=XXXXXXXXXXXX;"}

  }
]

Actual behavior

[
  {
    "id": "aa0d2668-1c3d-4432-b4a0-1dc2ba9f84a3",
    "name": "ManagementQueue",

    "definition":[]

  }
]

Steps to reproduce

ConfigRepo

public IEnumerable<EndPoint> GetEndPoints(Guid clientId)
        {
            var jsonString = "[{'id':'aa0d2668-1c3d-4432-b4a0-1dc2ba9f84a3','name': 'ManagementQueue','definition': {'ConnectionString' : 'Server=\\XXXXXX;Database=XXXXX;User Id=XXXXXXX;Password=XXXXXXXXXXXX;'}}]";

            var result = JsonConvert.DeserializeObject<IEnumerable<EndPoint>>(jsonString);
            return result;
        }

At this point when extract the properties of result it correctly shows the contents in JRaw field.

However, when passed through the controller its not.

[HttpGet]
        [Route("endpoints")]
        public async Task<ActionResult> GetAllEndPoints()
        {
            var result = _configRepo.GetEndPoints(Guid.Parse("ff935ab8-eb3a-43cf-a590-f6791658735b")));
            return Ok(result);
        }

This code used to work with .net core 2.2 getting content in Definition field.

Definition: {'ConnectionString' : 'Server=\\XXXXXX;Database=XXXXX;User Id=XXXXXXX;Password=XXXXXXXXXXXX;'}

But returns an empty array as the Definition when switched to .net core 3.0

Definition: []
hasithapg commented 4 years ago

Found the solution. Added below in my startup

services.AddControllers().AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();
            });

The default JSON serializer for ASP.NET Core 3.0 is changed to System.Text.Json. This doesn't fully compatible with NewtonSoft.Json de-serialized object return by the controller. So we need to add NewtonSoft default serializer settings.