using System;
using System.Text.Json;
using System.Text.Json.Serialization;
public class Program
{
public interface IB {
public int C { get; }
public int D { get; set; }
}
public class B : IB {
[JsonIgnore]
public int C => throw new Exception("i had JsonIgnore, but someone tried to serialize me :(");
public int D { get; set; }
}
public class A {
public IB B { get; set; }
}
public static void Main()
{
var a = new A();
a.B = new B();
a.B.D = 5;
Console.WriteLine(JsonSerializer.Serialize(a));
}
}
If object implementing an interface is passed into Serialize as interface, JsonIgnore is respected only on interface, not the class properties. In the code above, there is no way to work around it without modifying the classes themselves
Got:
Unhandled exception. System.Exception: i had JsonIgnore, but someone tried to serialize me :(
Expected:
{"B":{"D":5}}
.NET Core 3.1, System.Text.Json 4.7.2
This behavior strikes me as correct. _System.Text.Json_ is using statically available metadata, which means that the metadata would be read from _IB_, not from _B_.
You should in theory see the same behavior if you had:
public class MyBaseClass
{
public virtual int MyProperty { get; set; }
}
public class MyDerivedClass : MyBaseClass
{
[JsonIgnore]
public override int MyProperty { get; set; }
}
public void DoSerialization()
{
MyDerivedClass obj = new MyDerivedClass { MyProperty = 42 };
var serialized = JsonSerializer.Serialize<MyBaseClass>(obj);
// 'serialized' is expected to contain { "MyProperty": 42 }
}
(I haven't tested this sample. But it's what I would expect to be output.)
@GrabYourPitchforks is correct.
(I haven't tested this sample. But it's what I would expect to be output.)
That is indeed the output - https://dotnetfiddle.net/mpqIt4.
When polymorphic support is extended, part of the design would be to honor metadata on the actual type a property is being (de)serialized as - https://github.com/dotnet/runtime/issues/30083, https://github.com/dotnet/runtime/issues/29937.
Most helpful comment
This behavior strikes me as correct. _System.Text.Json_ is using statically available metadata, which means that the metadata would be read from _IB_, not from _B_.
You should in theory see the same behavior if you had:
(I haven't tested this sample. But it's what I would expect to be output.)