英語で読む

次の方法で共有


関連データとシリアル化

EF Core ではナビゲーション プロパティの修復が自動的に行われるので、最終的にオブジェクト グラフの循環が生じる可能性があります。 たとえば、ブログとその関連する投稿を読み込むと、投稿のコレクションを参照するブログ オブジェクトになります。 これらの各投稿には元のブログへの参照が含まれることになります。

一部のシリアル化フレームワークでは、このような循環は許可されていません。 たとえば、Json.NET では、循環が発生した場合に次の例外がスローされます。

Newtonsoft.Json.JsonSerializationException: Self referencing loop detected for property 'Blog' with type 'MyApplication.Models.Blog'.

System.Text.Json では、サイクルが見つかった場合も同様の例外がスローされます。

System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles. (System.Text.Json.JsonException: オブジェクト循環の可能性が検出されました。これは循環が原因であるか、オブジェクトの深度が許容されている最大深度 32 より大きい場合に発生する可能性があります。循環をサポートするよう JsonSerializerOptions で ReferenceHandler.Preserve を使用することを検討してください。)

ASP.NET Core で Json.NET を使用している場合は、オブジェクト グラフで見つかった循環を無視するように Json.NET を構成できます。 この構成は、Startup.csConfigureServices(...) メソッドで行われます。

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );

    ...
}

System.Text.Json を使用している場合は、次のように構成できます。

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
        });

    ...
}

もう 1 つの方法は、JSON シリアル化の循環の原因となるナビゲーション プロパティを無視することです。 Json.NET をしている場合は、いずれかのナビゲーション プロパティを [JsonIgnore] 属性で装飾し、シリアル化中にそのナビゲーション プロパティを走査しないように Json.NET に指示することができます。 System.Text.Json の場合は、[JsonIgnore] 属性を System.Text.Json.Serialization 名前空間で使用すると同じ効果が得られます。