JSON.Net自己参照ループが検出されました


111

私のウェブサイトには、4つのテーブル内にmssqlデータベースがあります。

私がこれを使うとき:

public static string GetAllEventsForJSON()
{
    using (CyberDBDataContext db = new CyberDBDataContext())
    {
        return JsonConvert.SerializeObject((from a in db.Events where a.Active select a).ToList(), new JavaScriptDateTimeConverter());
    }
}

このコードにより、次のエラーが発生します。

Newtonsoft.Json.JsonSerializationException:タイプ「DAL.Cyber​​User」のプロパティ「Cyber​​User」で自己参照ループが検出されました パス '[0] .EventRegistrations [0] .Cyber​​User.UserLogs [0]'。



私の答えが正しい場合は、それを正しいものとしてマークしていただけませんか?@Kovu
Muhammad Omar ElShourbagy 2016

回答:


211

私はちょうど親子コレクションで同じ問題を抱えていて、私の投稿を解決した投稿を見つけました。親コレクションアイテムのリストを表示したいだけで、子データは必要なかったため、以下を使用しましたが、正常に機能しました。

JsonConvert.SerializeObject(ResultGroups, Formatting.None,
                        new JsonSerializerSettings()
                        { 
                            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                        });

タイプに対してJSON.NETエラー自己参照ループが検出されました

また、次のJson.NET codeplexページも参照しています。

http://json.codeplex.com/discussions/272371

ドキュメンテーション:ReferenceLoopHandling設定


2
場合によっては、PreserveReferencesHandling = PreserveReferencesHandling.Objects;ここで説明するように使用することもでき ます:solve-self-referencing-loop-issue-when-when-using-newtonsoft-json
Dimitri Troncquo

WebAPI OData v4で、一部のタイプのデータがReferenceLoopHandling.IgnoreとPreserveReferencesHandling.Objectsの両方を必要とすることがわかりました
Chris Schaller

1
歌うAllelluiahのおかげで1によってそれほどまでしか投票権が十分ではありません
JP Chapleau

42

修正は、ループ参照を無視し、それらをシリアル化しないことです。この動作はで指定されていJsonSerializerSettingsます。

JsonConvert過負荷のあるシングル

JsonConvert.SerializeObject((from a in db.Events where a.Active select a).ToList(), Formatting.Indented,
    new JsonSerializerSettings() {
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
    }
);

これをデフォルトの動作にしたい場合は、Global.asax.csにコードを含むグローバル設定を追加 Application_Start()します。

JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
     Formatting = Newtonsoft.Json.Formatting.Indented,
     ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
};

リファレンス:https : //github.com/JamesNK/Newtonsoft.Json/issues/78


3
これを使用した
シリアル

これは、循環ループのあるオブジェクトがNHibernateモデルのPOCOである場合には機能しないようです(その場合、シリアル化によって大量のゴミが取得されるか、タイムアウトになることがあります)。
フェルナンドゴンザレスサンチェス

"IsSecuritySafeCritical":false、 "IsSecurityTransparent":false、 "MethodHandle":{"Value":{"value":140716810003120}}、 "Attributes":150、 "CallingConvention":1、 "ReturnType": "System.Void 、System.Private.CoreLib、Version = 4.0.0.0、Culture = neutral、PublicKeyToken = 7cec85d7bea7798e "、" ReturnTypeCustomAttributes ":{" ParameterType ":" System.Void、System.Private.CoreLib、Version = 4.0.0.0、Culture = neutral、PublicKeyToken = 7cec85d7bea7798e "、" Name ":null、" HasDefaultValue ":true、" DefaultValue ":null、" RawDefaultValue ":null、" MetadataToken ":134217728、" Attributes ":0、" Position ":-1、 "IsIn":false、 "IsLcid":false,。...など

37

ASP.NET Core MVCを使用している場合は、startup.csファイルのConfigureServicesメソッドにこれを追加します。

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

2
このソリューションはWebAPI EntityFramework Core 2.0でも動作することを確認しました
-

13

これはあなたを助けるかもしれません。

public MyContext() : base("name=MyContext") 
{ 
    Database.SetInitializer(new MyContextDataInitializer()); 
    this.Configuration.LazyLoadingEnabled = false; 
    this.Configuration.ProxyCreationEnabled = false; 
} 

http://code.msdn.microsoft.com/Loop-Reference-handling-in-caaffaf7


4
これは、非同期メソッドも使用している場合に最適な方法です。それは本当の痛みになる可能性がありますが、それ以外の場合に発生するであろう多くの問題(この問題を含む)を解決し、使用するものを照会するだけなので、パフォーマンスが大幅に向上します。
Josh McKearin、2015年

xyz.edmxで、デフォルトで非表示になるxyz.Context.vbファイルを開きます。これは、codePublic Sub New()Mybase.New( "name = EntityConName")End Sub を持ち codeます。End Subの前に、codeMe.Configuration.LazyLoadingEnabled = False Me.Configuration.ProxyCreationEnabled = Falseを追加 code します。これにより、webapiからのjson出力の「自己参照ループ」エラーが解消されます。
ベンカット

これではうまくいかないことがわかりました。AsNoTracking()を使用して修正しました。多分誰かを助ける
スコットサンペドロ

@scottsanpedro私たちがあなたのコードを見ることができればもっと良かったです。
ddagsan

6

オブジェクト参照の保持を設定する必要があります。

var jsonSerializerSettings = new JsonSerializerSettings
{
    PreserveReferencesHandling = PreserveReferencesHandling.Objects
};

次に、クエリを次のvar q = (from a in db.Events where a.Active select a).ToList();ように呼び出します

string jsonStr = Newtonsoft.Json.JsonConvert.SerializeObject(q, jsonSerializerSettings);

参照:https : //www.newtonsoft.com/json/help/html/PreserveObjectReferences.htm


4

モデルクラスに「[JsonIgnore]」を追加します

{
  public Customer()
  {
    Orders = new Collection<Order>();
  }

public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }

[JsonIgnore]
public ICollection<Order> Orders { get; set; }
}

3

Dot.Net Core 3.1を使用していて、

「Newtonsoft.Json.JsonSerializationException:プロパティの自己参照ループが検出されました」

簡単に参照できるように、これをこの質問に追加します。Startup.csファイルでは、以下を使用する必要があります。

 services.AddControllers()
                .AddNewtonsoftJson(options =>
                {
                    // Use the default property (Pascal) casing
                    options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                });

2

asp.netコア3.1.3の場合、これは私のために働きました

services.AddControllers().AddNewtonsoftJson(opt=>{
            opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        });

1

JsonConvert.SerializeObject(ObjectName, new JsonSerializerSettings(){ PreserveReferencesHandling = PreserveReferencesHandling.Objects, Formatting = Formatting.Indented });


6
このコードは質問に答えることがありますが、このコードが質問に答える理由や方法に関する追加のコンテキストを提供すると、長期的な価値が向上します。
Alex Riabov

1

タイプクラスが他のクラスへの参照を持ち、そのクラスがタイプクラスへの参照を持っているためにループが発生する場合があるため、このコードのように、json文字列で正確に必要なパラメーターを選択する必要があります。

List<ROficina> oficinas = new List<ROficina>();
oficinas = /*list content*/;
var x = JsonConvert.SerializeObject(oficinas.Select(o => new
            {
                o.IdOficina,
                o.Nombre
            }));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.