I've run into a weird issue with Serialization/Deserialization of a Dictionary when hidden in a backing field behind a property.
Here is the Fiddle: https://dotnetfiddle.net/RFZEur
End Result:
- Language: C#
- Framework: .Net Framework 4.8
- Have a private backing field that has an combination of pairings with <int, string>
- Can be Serialized into a list of strings (No ints included, pointing to the backing field referenced)
- Cannot be Deserialized from the Serialized list -- the backing dictionary does not get populated.
public class SanityChecks
{
private readonly ITestOutputHelper _testOutputHelper;
public SanityChecks(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}
public class TestClass
{
[JsonIgnore]
public Dictionary<int,string> _prvList = new Dictionary<int, string>();
public IEnumerable<string> ListValues
{
get => _prvList.Select(p=> p.Value).ToList();
set
{
var valArr = value.ToArray();
for (var x = 0; x < valArr.Length; x++)
{
_prvList.Add(x,valArr[x]);
}
}
}
}
[Fact]
public void SanityCheck_CanDeserialize()
{
var assumption = "{\"ListValues\":[\"TestValue\",\"AAA\"]}";
var actual = JsonConvert.DeserializeObject<TestClass>(assumption);
Assert.Equal(2, actual._prvList.Count());
Assert.Equal(2, actual.ListValues.Count());
}
[Fact]
public void SanityCheck_CanSerialize()
{
var assumption = new TestClass() { ListValues = new[] { "TestValue", "AAA" } };
var actualSerialized = JsonConvert.SerializeObject(assumption);
_testOutputHelper.WriteLine(actualSerialized);
Assert.Equal("{\"ListValues\":[\"TestValue\",\"AAA\"]}", actualSerialized);
}
[Fact]
public void SanityCheck_CanDeserializeFromSerialized()
{
var assumption = new TestClass() { ListValues = new[] { "TestValue", "AAA" } };
var actualSerialized = JsonConvert.SerializeObject(assumption);
_testOutputHelper.WriteLine(actualSerialized);
var actualDeserialized = JsonConvert.DeserializeObject<TestClass>(actualSerialized);
Assert.Equal(2, actualDeserialized._prvList.Count());
var actualDeserializedSerialized = JsonConvert.SerializeObject(actualDeserialized);
_testOutputHelper.WriteLine(actualDeserializedSerialized);
Assert.Equal(actualSerialized, actualDeserializedSerialized);
}
}
If you have some advice on how to retrieve this result, I'm open. I'm using XUnit for testing purposes, however the fiddle has a quick implementation of the tests below with slight modifications to make it a console application.
I've attempted with an implementation of ISerializable
into the object, however I ran into the same issue.
Noted Weirdness: The removal of the Get Clause within the IEnumerable
causes the deserialization to work (the serialization no longer works)
Edit: For additional clarity, I need the mapping of int,string pairings to be serialized as a list of strings, and I need that same serialized version to be deserializable as a collection of int,string pairings.
For the Fiddle: There should be no exceptions thrown For the XUnit: All tests should pass.