0

この状況の環境:

  • asp.net mvc 3
  • c#
  • エンティティ フレームワーク 4.3.1
  • JavaScriptシリアライザー

    としてマークアップされたフィールドを含めると便利な状況に遭遇しました[ScriptIgnore]。フィールドを属性なしのままにしておくと、循環参照が構成され、例外がスローされます。理由は次のようなものです。

    public class Foo
    {
     public int FooId { get; set; }
    
     [ScriptIgnore]
     public virtual Collection<Bar> Bars { get; set; }
    }
    
    public class Bar
    {
     public int BarId { get; set; }
     public int FooId { get; set; }
     public virtual Foo Foo { get; set; }
    }
    

    ここでわかるように、 にFooは多くの が関連付けられていBarsます。そして aBarには が関連付けられていFooます。

    状況に戻ります。include ステートメントを使用して、この関連付けをコントローラーにロードしています。

    .Include( foo => foo.Bars );
    

    include は[ScriptIgnore]注釈の影響を受けないため、スローされるエラーはありません。デバッグ時に検査すると、関連付けが適切に構築されます。のリストがありfoos、それぞれfooに の関連リストがありBarsます。

    ここで、この構築されたリストをシリアル化したいと思います。データでいっぱいになるビューモデルがあります。次のようになります。

    public class FooView
    {
     public List<Foo> Foos { get; set; }
    
     public string AsJson()
     {
      var serializer = new JavaScriptSerializer();
      return serializer.Serialize(this);
     }
    }
    

    したがって、このビューモデルをビューに渡してシリアル化します。

    @model FooView
    <script type="text/javascript">
     var fooViewModel = @( Html.Raw( Model.AsJson() ) );
    </script>
    

    例外はスローされませんが、シリアライゼーションは でBarsマークされたフィールド ( ) を適切にスキップし[ScriptIgnore]ます。調べconsol.log(fooViewModel)てみると、 の配列があることは明らかですが、 のいずれにもFooの関連する配列はありません。BarFoos

    [ScriptIgnore]このタグを一度だけスキップする方法はありますか? 毎回スキップした場合、シリアライザーは Foo をシリアル化し、Bar 型のコレクションを見て確認し、各 Bar をシリアル化し、Bar に関連付けられた Foo があることに気付き、Foo をシリアル化し、Foo に Bar 型のコレクションがあることに気付きます.. 。等。Bar初めてのコレクションだけをつかみたい。これを達成する方法はありますか?FooBarからシリアル化しようとしますが、空になります。これはすべて熱心な読み込みで行われ、オブジェクト グラフ全体が既に構築されています。

  • 4

    1 に答える 1

    2

    私がこれに遭遇したとき、私がやったのは、具体的には設定を持つJson.NETシリアライザーでシリアライザーを置き換えることでした

    _jsonSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    

    Json.NET は、参照ループ内のオブジェクトを無視し、シリアル化しません。オブジェクトが最初に検出されたときは、通常どおりシリアル化されますが、オブジェクトがそれ自体の子オブジェクトとして検出された場合、シリアライザーはそのシリアル化をスキップします。

    設定の情報はhttp://james.newtonking.com/projects/json/help/index.html?topic=html/SerializingJSON.htm で、私はhttp://blogs.msdn.com/b/henrikn/を使用しましたarchive/2012/02/18/using-json-net-with-asp-net-web-api.aspx を使用してシリアライザーを置き換え、それをデフォルトとして global.asax.cs に追加します。

    configuration.Formatters.Insert(0, new JsonNetFormatter(serializerSettings));
    

    これが回避策であることは認識していますが (実際には scriptignore を扱っているわけではありません)、提供されたデータベースから非常に多くの循環参照があったため、当時はこれが最善の解決策であると思われました。

    于 2012-10-08T20:01:15.007 に答える