3

ASP.NETMVCフロントレイヤーを介してサーバーからJSONリストを返そうとしています。

var stuff = repo.GetStuff();
return Json(stuff);

ただし、予期されたJSONの代わりに、次のようなエラーメッセージが表示されます

タイプ'System.Reflection.RuntimeModule'のオブジェクトをシリアル化しているときに、循環参照が検出されました。

私はこれがどこで起こるかを見つけたと思いますが、それを説明するために、次のような簡単なドメインモデルの例が必要です。

ここに画像の説明を入力してください

私は(怠惰に?)NHibernateから選択したドキュメントを次のようにロードしています:

var session = getNHibernateSession();
var query = new NhQueryable<Document>(session.GetSessionImplementation());
var docs = query.ToList().AsEnumerable();

次に、ドキュメントを渡しJsonResultてコントローラーにを返します。

return Json(docs, JsonRequestBehavior.AllowGet);

これでJson()、コレクションを封印すると、ドキュメントのプロパティを調べて人を見つけます。その人をシリアル化し、プロジェクトを見つけます。それはプロジェクトをシリアル化し、-そうです-その人を再び見つけます!私は遅延読み込みを行っているので、何も停止しなくてもずっと歩き続けることができますが、循環参照エラーによって停止します。

これらすべてのレベルを下げる必要はありません(最初にプロジェクトをロードしなくても大丈夫です)-Json()たとえば、2レベル下がらないように、このコレクションのシリアル化方法に何らかの影響を与えることができますか?少し調べてみましたが、ほとんどの場合、.NET MVCの組み込み機能を使用するのではなく、シリアル化ライブラリを直接使用することにした人からのもののようです。(注:この問題の解決策は、この場合に特に適用できる必要があります。アプリケーション内のどこかで、プロジェクトを含む人々のJSONリストを取得したい場合があるからです...)

4

3 に答える 3

1

Json を取得している場合は、サービス API があります。実装以外に API を設計する必要があります。それを使用するページには、これらすべてのフィールドとコレクションが必要ですか? おそらくそうではありません。他の機能やサービスのプロパティを追加するのはどうですか? それらはすべてのリクエストに表示されるようになります。

必要なのは、ViewModel または目的の構造を持つ匿名型を使用することです。

var session = getNHibernateSession();
var query = new NhQueryable<Document>(session.GetSessionImplementation());
var docs = query.ToList();
var result = query.Select(x => new {
                                       x.Id,
                                       x.Name,
                                       People = new { p.Id, 
                                                      p.Name, 
                                                      p.Title
                                                    }
                                    });

return Json( result, JsonRequestBehavior.AllowGet);

このようにして、何をどのようにレンダリングするかを制御できます。

于 2012-06-20T14:09:55.950 に答える
0

オブジェクト参照を JSON に保持するには、次のコードをGlobal.asaxファイルのApplication_Startメソッドに追加します。

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
于 2014-04-07T10:06:06.963 に答える
0

すでに回答されています here .

また、通常、ドメイン エンティティをこのように公開することはお勧めできません。読み取り専用の場合はそれほど悪くないかもしれませんが、アクション メソッドのいずれかがドメイン エンティティを受け入れる場合、特別にフォーマットされたリクエストによって、ドメイン エンティティの不要なプロパティ (PK など) が上書きされる可能性があります。 )。

于 2012-06-20T13:57:09.660 に答える