2016-08-08 6 views
1

2つの送信アクションでビューMyView.chstmlをセットアップしましたが、「シリアル化中に循環参照が検出されましたタイプ 'System.Reflection.RuntimeModule'のオブジェクトです。簡単にトラブルシューティングを行うには?理由を見つける方法 "シリアライズ中に循環参照が検出されました...." System.Reflection.RuntimeModule '

@using (Html.BeginForm("MyView", "Worker", FormMethod.Post, new { enctype = "multipart/form-data", @name = "formWorker" })) 
{ 
    @Html.AntiForgeryToken() 
    <div class="form-horizontal" id="divWork"> .... 
     <div class="form-group"> 
      <button id="btnSubmit" class="btn btn-success" type="submit" value="Work1">Work1</button> 
     </div> 
     <div id="Dynamictable" class="table-responsive hidden" name="dtable"> 
       <table class="table table-bordered" id="dctable" name="dctable"></table> 
     </div> 

     <div id="dialogsubmit" title="second submit"> 
       <div id="dialog-content" name="dialog-content" class="form-control hidden"> &nbsp;</div> 
      </div> 
    </div> 

、スクリプトで

(function() { 
    //strangely the below ajax is never called 
    $('#formWorker').submit(function() { 
     debugger; 
     $.ajax({ 
       url: this.action, 
       type: this.method, 
       data: $(this).serialize(), 
       success: function (result) { 
        debugger; 
        bootbox.alert(result); 
       } 
      }); 
      // it is important to return false in order to 
      // cancel the default submission of the form 
      // and perform the AJAX call 
      return false; 
    }); 
    } 
     $("#btnSubmit").click(function() { 

     if(document.getElementById('dctable').getElementsByTagName("tr").length < 1) 
     { 
      aRow = document.all("dctable").insertRow(); 
      var oCell = aRow.insertCell(); 
      oCell = newRow.insertCell(); 
      oCell.innerHTML = '<input type="submit" name="submit2" value="submit2" />'; 
      **//strangely if i replace the above RHS with below, it act as submit halft submit form (half becuase the FormCollection object in HttpPost method of controller lacks key submit2 and also HttpPostedFileBase object came as null in controller method ,** 
      *//'<button id="submit2" name="submit2" class="btn submit2" value="submit2" ><i class="fa fa-search"></i> submit2</button>'* 
      return false; 
     } 

     }); 



    </script> 
コントローラで

 [HttpGet] 
     public ActionResult Worker() 
     { 
      return View(); 
     } 

     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public ActionResult Worker(HttpPostedFileBase file, FormCollection form) 
     { 
      string value = form["submit2"]; //half submit form as it is null in additon to file is null. if i use commented RHS , all good here, but no option in view to process the output in same view. 
      IEnumerable<object> data = Enumerable.Empty<object>(); 
      if (value != null) // key doesn't exist 
      { 
      //process here and and return json to shown result on same page using popup/alert. 
      return this.Json(
       new 
       { 
        Result = data.ToList() 
       }, JsonRequestBehavior.AllowGet 
      ); 
      } 
      return PartialView("anoterhView", data.ToList()); 
     } 

答えて

1

JSONシリアライザを効果的にシリアル化の無限ループを生じさせるループを開始したときに循環参照例外は一般に投げられます。これは、シリアライズ可能なプロパティのスキーマを見るときに発生します。あなたは私たちは2つの単純なクラス、Nodeを入力しているパブリックプロパティParentを持ってNodeクラスを持って見ることができるように

public class Node 
{ 
    public Node Parent { get; set; } 
} 
public class Parent : Node 
{ 
    public List<Node> Children { get; set; } = new List<Node>(); 
} 

:たとえば:

は、以下の2つのクラスを取ります。今度は、Parentクラスを見ると、Nodeから始まり、Childrenという属性がList<Node>です。ここでは、循環依存関係の問題が発生します。次の簡単な方法を考えてみましょう。

public string SerializeJsonObject() 
{ 
    var parent = new Parent(); 
    var child = new Node(); 
    child.Parent = parent; 
    parent.Children.Add(child); 

    return Json(parent); 
} 

この方法はParentオブジェクトparent、次いでNodeオブジェクトchildを構築します。次にParentプロパティをchildに設定してparentインスタンスに設定します。次に、Addchildを親のChildrenリストに置き換えます。

親のシリアライズを考えてみましょう。私達は私達の循環依存関係を見ることができます。このことから

-- Parent Item 
    -- Parent: null no procesing 
    -- Children : Serialize each Node object 
     -- Node 1 
     -- Parent 
      -- Parent: null no processing 
      -- Children: 
       -- Node 1 
        -- Parent 
        --Parent: null no processing 
        --Children: 
         -- Node 1 
          ..... continues forever never finishing serializing Node 1 

は、ParentChildrenコレクションでNodeへの参照を持っているので、しかし、それは唯一の循環参照ですParentプロパティです。したがって、シリアライザはオブジェクトのシリアライズを完了できません。

これはリストに限定されず、2つのクラスが互いに参照を持ち、両方とも直列化可能である同様の例を見ることができます。次のクラスを考えてみましょう。

public class Node 
{ 
    public string Name { get; set; } 

    public Node Previous { get; set; } 

    public Node Next { get; set; } 
} 

このクラスは、両方PreviousNextプロパティのNodeに依存しています。したがって、小さなデータセットを構築する方法が与えられています。

public static object SerailizeANode() 
{ 
    Node first = null; 
    Node previous = null; 
    for(var i = 0; i < 10; i++) 
    { 
     var current = new Node(); 
     current.Name = $"Node {i}"; 
     if(previous != null) 
     { 
      previous.Next = current; 
      current.Previous = previous; 
     } 
     previous = current; 

     if (first == null) 
      first = current; 
    } 
    return Json(first); 
} 

これは本当に簡単ですが、1-9 Previousノードへの依存関係を持っている2-10Nextノードとオブジェクトの依存関係を持っている10個のオブジェクトで終わります。だから我々は、シリアライザは、循環参照(無限ループ)をヒットさせプロパティ(Previous & Next)の依存関係のシリアライズで見るように再びfirst

-- first 
    -- Name: Node 0 
    -- Previous: Null 
    -- Next: 
     -- Name: Node 1 
     -- Previous 
     -- Name: Node 0 
     -- Previous: null 
     -- Next: 
      -- Name: Node 1 
      -- Previous: 
       -- Name: Node 0 
       -- Previous: null 
       -- Next: 
        --Name: Node 1 
        continues on forever. 

のシリアライズを与えられ、例外がスローされます。

よくコメントされたセクションからブラウザに戻ってくるデータにも同様の問題があります。

//process here and and return json to shown result on same page using popup/alert. 
return this.Json(new 
       { 
        Result = data.ToList() 
       }, JsonRequestBehavior.AllowGet); 

あなたはより多くの情報が必要な場合は、コメントアウトセクションで返されるクラスのスキーマを投稿してください可能性があります。

関連する問題