ポリモーフィズムや参照の保持などの特定のコンテキストでは、 System.Text.Json はメタデータを出力するための特定のプロパティ名 ( $type、 $id、 $refなど) を予約します。
TypeDiscriminatorPropertyNameなどの一部のプロパティ名は、カスタム名で構成することもできます。 以前は、シリアライザーは、これらのプロパティ名がユーザー定義コントラクトと競合するかどうかの検証を実行しませんでした。これにより、プロパティが重複し、あいまいであったかラウンドトリップに失敗した JSON が生成される可能性があります。 .NET 10 以降では、System.Text.Json を使用すると、このような構成を防ぐための検証が可能になり、ユーザーに早期警告が表示されます。
導入されたバージョン
.NET 10
以前の動作
以前は、次のコードは、重複する Type プロパティを持つ無効な JSON オブジェクトを生成し、 JsonExceptionで逆シリアル化できませんでした。
using System.Text.Json;
using System.Text.Json.Serialization;
string json = JsonSerializer.Serialize<Animal>(new Dog());
Console.WriteLine(json); // {"Type":"dog","Type":"Dog"}
JsonSerializer.Deserialize<Animal>(json); // JsonException: Deserialized object contains a duplicate 'Type' metadata property.
[JsonPolymorphic(TypeDiscriminatorPropertyName = "Type")]
[JsonDerivedType(typeof(Dog), "dog")]
public abstract class Animal
{
public abstract string Type { get; }
}
public class Dog : Animal
{
public override string Type => "Dog";
}
新しい動作
.NET 10 以降では、同じ型をシリアル化しようとすると、早期検証エラーが発生します。
InvalidOperationException: 型 'Dog' には、既存のメタデータ プロパティ名と競合するプロパティ 'Type' が含まれています。 名前を変更するか、JsonIgnoreAttribute で無視することを検討してください。
この検証エラーは、シリアライザーが最初に作成されたとき、またはシリアル化が最初に試行されたときに発生し、無効なシリアル化コントラクトが早期に検出されます。
破壊的変更の種類
この変更は 動作の変更です。
変更の理由
この変更により、無効なシリアル化コントラクトが早期に防止されます。 プロパティ名を事前に検証することで、シリアライザーは、重複するプロパティが出力されるシナリオを防ぎ、正しくラウンドトリップできない無効な JSON を生成します。 これにより、開発者は、逆シリアル化中に実行時に検出するのではなく、開発中に構成の問題を特定して修正できます。
詳細については、以下を参照してください。
- [STJ]メタデータ プロパティ名と競合するプロパティ名を許可しない (dotnet/runtime#106390)
- プロパティ名がメタデータと競合する型を禁止する (dotnet/runtime#106460)
推奨されるアクション
System.Text.Json 固有のメタデータ プロパティ ( $type、 $id、 $refなど) と競合するプロパティ名は使用しないでください。 このようなプロパティをクラスに保持する必要がある場合は、競合するプロパティに JsonIgnoreAttribute 注釈を適用します。
影響を受ける API
.NET