Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.Text.Json fails to deserialize an array of POCO's inside another POCO #30980

Closed
MarkStega opened this issue Sep 26, 2019 · 1 comment
Closed

Comments

@MarkStega
Copy link

It appears that System.Text.Json.Deserialize does not properly handle an array of POCO's inside another POCO.

Build the following console application:
`
using Newtonsoft.Json;
using System;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello Json!");

        string json = "{\"pStatus\":0,\"pError\":\"\",\"pResult\":[{\"processIdentifier\":"
            + "\"ANES - 2019 - 9955\",\"associatedProcessIdentifier\":\"\",\"dashboard\":\" "
            + "| SPD_Version | 5 | SPD_AnesthesiaType | Choice | SPD_BloodProducts ||\"},"
            + "{\"processIdentifier\":\"ANES - 2019 - 9964\",\"associatedProcessIdentifier\":\"\","
            + "\"dashboard\":\" | SPD_Version | 5 | SPD_AnesthesiaType | Choice | SPD_BloodProducts ||\""
            + "}]}";

        var newton = Newtonsoft.Json.JsonConvert.DeserializeObject<ServiceResult<Process_DD[]>>(json);

        var stjo = new System.Text.Json.JsonSerializerOptions();
        stjo.PropertyNameCaseInsensitive = true;
        var stj = System.Text.Json.JsonSerializer.Deserialize<ServiceResult<Process_DD[]>>(json, stjo);
    }
}

public class ServiceResult<ServiceResultType>
{
    public enum eStatus { OK, Error };
    public eStatus pStatus { get; set; }
    public string pError { get; set; }
    public ServiceResultType pResult { get; set; }

    public ServiceResult() { }
    public ServiceResult(
        ServiceResultType p_Result,
        eStatus p_Status = eStatus.OK,
        string p_Error = "")
    {
        pStatus = p_Status;
        pError = p_Error;
        pResult = p_Result;
    }
}

public class Process_DD
{
    public string ProcessIdentifier;
    public string AssociatedProcessIdentifier;
    public string Dashboard;

    public Process_DD()
    {
    }
    public Process_DD(string processIdentifier, string associatedProcessIdentifier, string dashboard)
    {
        this.ProcessIdentifier = processIdentifier;
        this.AssociatedProcessIdentifier = associatedProcessIdentifier;
        this.Dashboard = dashboard;
    }
}

}
using the following csproj:
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
</ItemGroup>

</Project>
`
Debug the program and step through both deserializations. Note that the Newtonsoft result has appropriate values for the two array elements of type Process_DD. The System.Text.Json result has null values for the properties.

C:\Users\ms>dotnet --info
.NET Core SDK (reflecting any global.json):
Version: 3.0.100
Commit: 04339c3a26

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18362
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100\

Host (useful for support):
Version: 3.0.0
Commit: 7d57652f33

.NET Core SDKs installed:
2.1.802 [C:\Program Files\dotnet\sdk]
2.2.402 [C:\Program Files\dotnet\sdk]
3.0.100 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
https://aka.ms/dotnet-download

@ahsonkhan
Copy link
Member

Process_DD does not contain any public properties with getter/setters and relies on non-default ctor. Only parameterless ctor and POCOs with properties is currently supported.

In general, deserializing an array of POCOs inside another POCO works correctly, for types that fit the above constraint.
If you change your object model to contain properties, things work as expected:

public class Process_DD
{
    // Public properties work, fields don't
    public string ProcessIdentifier { get; set; }
    public string AssociatedProcessIdentifier { get; set; }
    public string Dashboard { get; set; }

    public Process_DD()
    {
    }
    public Process_DD(string processIdentifier, string associatedProcessIdentifier, string dashboard)
    {
        this.ProcessIdentifier = processIdentifier;
        this.AssociatedProcessIdentifier = associatedProcessIdentifier;
        this.Dashboard = dashboard;
    }
}

POCOs with fields are not yet supported which is why you are seeing this behavior. Here's the issue: https://github.com/dotnet/corefx/issues/36505

Closing this as duplicate. @MarkStega, please feel free to re-open if you believe the issue is elsewhere. I have moved your comment there.

@msftgits msftgits transferred this issue from dotnet/corefx Feb 1, 2020
@msftgits msftgits added this to the 5.0 milestone Feb 1, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants