web-dev-qa-db-ja.com

Json型のオブジェクトのシリアル化中に循環参照が検出されました

クラスを与えます:

public class Parent
{
    public int id {get; set;}
    public int name {get; set;}

    public virtual ICollection<Child> children {get; set;}
}

[Table("Child")]
public partial class Child
{
    [Key]
    public int id {get; set;}
    public string name { get; set; }

    [NotMapped]
    public string nickName { get; set; }
}

そしてコントローラーコード:

List<Parent> parents = parentRepository.Get();
return Json(parents); 

LOCALHOSTでは機能しますが、ライブサーバーでは機能しません。

エラー:Json型のオブジェクトのシリアル化中に循環参照が検出されました

検索して[ScriptIgnore]属性を見つけたので、モデルを

using System.Web.Script.Serialization;

public class Parent
{
    public int id {get; set;}
    public int name {get; set;}

    [ScriptIgnore]
    public virtual ICollection<Child> children {get; set;}
}

ただし、ライブサーバー(win2008)でも同じエラーが発生します。

このエラーを回避して、親データを正常にシリアル化するにはどうすればよいですか?

23
Expert wanna be

次のコードを試してください:

return Json(
    parents.Select(x => new {
        id = x.id,
        name = x.name,
        children = x.children.Select(y => new {
            // Assigment of child fields
        })
    })); 

...または親プロパティのみが必要な場合:

return Json(
    parents.Select(x => new {
        id = x.id,
        name = x.name
    })); 

実際には問題の解決策ではありませんが、DTOをシリアル化するときの一般的な回避策です...

47
RMalke

同様の問題が発生し、同様に根本的な問題を解決できませんでした。サーバーがjson.encodeを介してjsonに変換するためにlocalhostとは異なるdllを使用していると思います。

ここに質問と解決策を投稿しました Json.Encodeでシリアル化中に循環参照が検出されました

私はmvchelperで解決しました。

2
David

このコードを使用できますが、列のフィルタリングに拡張機能の選択を使用しないでください。

var list = JsonConvert.SerializeObject(Yourmodel,
    Formatting.None,
    new JsonSerializerSettings() {
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
});
return list;
2
Mohsen Rahimi

MVC5ビューでKnockoutを使用しているため、修正を使用しています。

アクションで

return Json(ModelHelper.GetJsonModel<Core_User>(viewModel));

関数

   public static TEntity GetJsonModel<TEntity>(TEntity Entity) where TEntity : class
    {
        TEntity Entity_ = Activator.CreateInstance(typeof(TEntity)) as TEntity;
        foreach (var item in Entity.GetType().GetProperties())
        {
            if (item.PropertyType.ToString().IndexOf("Generic.ICollection") == -1 && item.PropertyType.ToString().IndexOf("SaymenCore.DAL.") == -1)
                item.SetValue(Entity_, Entity.GetPropValue(item.Name));
        }
        return Entity_;  
    }
1
A.Kosecik