-
DescriptionI'm building a tool that builds a JSON object to match a third-party system, so if the example seems convoluted.. welcome to my world. Note also that I need only to serialize the .NET objects to JSON - my bug report deal only with serialization as I have not implemented or tested deserialization at all. The crux of the problem appears to be the use of the However, with the Reproduction Stepsusing System.Text.Json;
using System.Text.Json.Serialization;
namespace MyTests;
[TestClass]
public class ThisIsATest
{
[TestMethod]
public void Test1()
{
var opt = new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
var testBase = new TestBase
{
CollectionA = new List<ITestSet>()
};
var setA = new TestSet(
new List<Dictionary<string, List<string>>>
{
new ()
{
{"test", new List<string> {"a", "b"}}
},
new ()
{
{"test2", new List<string>{"c", "d"}}
}
});
testBase.CollectionA.Add(setA);
var result = JsonSerializer.Serialize(testBase, opt);
const string expected = """
{"collection-a":[{"data":[{"test":["a","b"]},{"test2":["c","d"]}]}]}
""";
Assert.AreEqual(expected, result);
}
}
public sealed record TestBase([property: JsonPropertyName("collection-a")] List<ITestSet>? CollectionA = null, [property: JsonPropertyName("collection-b")] List<ITestSet>? CollectionB = null);
public sealed record TestSet([property: JsonPropertyName("data")] List<Dictionary<string, List<string>>>? Data = null) : ITestSet;
public interface ITestSet {} Merely execute the above as-is in a MSTest project. I don't think it'll be relevant, but this is using .NET 7 and the following packages in my test project: <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="coverlet.collector" Version="3.2.0" /> Expected behaviorI expect the unit test to pass because the serialized result matches the expected value. Specifically, because I'm populating the collection with a concrete implementation of the ITestSet, I expect that the serializer is using the shape of the concrete implementation rather than the empty shape of the interface. Actual behaviorThe serializer does not produce the expected value. Regression?Don't know - only wrote this today Known WorkaroundsDrop the Configuration.NET 7 I don't believe this issue to be at all specific to this configuration. Other informationDropping the use of This one is what's used in the example above. public sealed record TestSet([property: JsonPropertyName("data")] List<Dictionary<string, List<string>>>? Data = null) : ITestSet; I also have to support this one. CollectionA and CollectionB may be populated with either of these public sealed record OtherTestSet([property: JsonPropertyName("data")] List<Dictionary<string, string>>? Data = null) : ITestSet; That's why I'm using a list of ITestSet with these two slightly differently shaped types. What's not clear to me is why the serializer uses the empty interface shape instead of the concrete class shape. Thank you for the assist! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Have you read the part about polymorphic serialization? |
Beta Was this translation helpful? Give feedback.
Have you read the part about polymorphic serialization?
https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism?pivots=dotnet-7-0