2016-11-23 11 views
5

記事に複数のコメントがある小さなデモを設定しようとしました。記事の詳細ビューは、コメントを部分的に表示する必要があります。 partialView自体には、新しいコメントを追加するための別の部分的なビューが含まれています。PartialViewはなぜ自分自身を呼び出し続けますか?

別のコメントを追加しようとすると、コントローラのアクションが自分自身を呼び出し続けているため、InsufficientExecutionStackExceptionが届きます。なぜこれが起こるのですか?

(。誰かが手元に教材を持っている場合は同様の例は、MSFT 70から486のコースにモジュール9である必要があり、それは私が構築しようとするものです。)

編集:完全なコードがオンになっていますgithub

Edit2: Githubのサンプルが修正されました。 Stephen Mueckeが指摘したように、GETPOSTの両方のメソッド名が同じ名前のハットが循環参照を引き起こしていたという事実が指摘されています。 これ以上の人々が指摘する前に、DIモデルとビューモデルは欠落しており、すべてのコメントを再レンダリングすることは最適ではありません:はい私は気付いています。これはちょうどクイックn汚いデモだった。

コントローラー:

[ChildActionOnly] 
public PartialViewResult _GetCommentsForArticle(int articleId) 
{ 
    ViewBag.ArticleId = articleId; 
    var comments = db.Comments.Where(x => x.Article.ArticleId == articleId).ToList(); 
    return PartialView("_GetCommentsForArticle", comments); 
} 


public PartialViewResult _CreateCommentForArticle(int articleId) 
{ 
    ViewBag.ArticleId = articleId; 
    return PartialView("_CreateCommentForArticle"); 
} 

[HttpPost] 
public PartialViewResult _CreateCommentForArticle(Comment comment, int articleId) 
{ 
    ViewBag.ArticleId = articleId; 
    comment.Created = DateTime.Now; 
    if (ModelState.IsValid) 
    { 
     db.Comments.Add(comment); 
     db.SaveChanges(); 
    } 
    var comments = db.Comments.Where(x => x.Article.ArticleId == articleId).ToList(); 
    return PartialView("_GetCommentsForArticle", comments); 
} 

条についてDetails.cshtmlで該当する行:

@Html.Action("_GetCommentsForArticle", "Comments", new { articleId = Model.ArticleId}) 

_GetCommentsForArticle:

@model IEnumerable<Mod9_Ajax.Models.Comment> 
<div id="all-comments"> 
    <table class="table"> 
     <tr> 
      <th> 
       @Html.DisplayNameFor(model => model.Text) 
      </th> 
     </tr> 

     @foreach (var item in Model) 
     { 
      @* ... *@ 
     } 
    </table> 
</div> 
@Html.Action("_CreateCommentForArticle", "Comments", new { articleId = ViewBag.ArticleId }) 

_CreateCommentForArticle:

@model Mod9_Ajax.Models.Comment 
@using (Ajax.BeginForm("_CreateCommentForArticle", "Comments", new AjaxOptions 
{ 
    HttpMethod = "POST", 
    InsertionMode = InsertionMode.Replace, 
    UpdateTargetId = "all-comments" 
})) 
{ 
    @* ... *@ 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Create" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 
+0

に合うようにフォームを変更することができますEntity ModelクラスをViewModelまたはDTOとして使用することは悪いことです。エンティティモデルタイプを再利用するのではなく、常に専用のViewModel/DTOタイプを使用してください。 – Dai

+1

単純な 'CommentsController :: Details'アクションであなたのビューを新しい空のプロジェクトに複製しましたが、私はこの問題を再現できません。プロジェクト全体をどこかのZip/archiveに投稿できますか? – Dai

+0

POSTメソッドは、(ビューに新しいコメントを追加するのではなく)すべてのコメントをビューに戻したときにそれを返すのはなぜですか? –

答えて

1

何が起こっているのかを説明するために、_CreateCommentForArticle()メソッドを投稿するフォームがあり、_GetCommentsForArticle.cshtmlの部分が@Html.Action("_CreateCommentForArticle", ...)を含むようにレンダリングされます。

ビューが正しくレンダリングされますが、フォームを送信する際に、 _GetCommentsForArticleページに対する現在の要求が [HttpPost]方法なので、 @Html.Action()[HttpPost]方法(ない [HttpGet]メソッドを探します Details()の初期GETメソッドで

)。その結果、[HttpPost]は部分的に_GetCommentsForArticle.cshtmlをレンダリングし、_GetCommentsForArticle.cshtmlをレンダリングする_CreateCommentForArticle() POSTメソッドを再度呼び出すので、メモリが足りなくなり例外がスローされます。

あなたが例えば

[HttpPost] 
public PartialViewResult Create(Comment comment, int articleId) 

、POSTメソッドの名前を変更することでこの問題を解決し、トレーニング材料はにあなたを指示された場合、余談として

@using (Ajax.BeginForm("Create", "Comments", new AjaxOptions { ... 
+0

私はラボに座っていて、同じ結論に達しました。これは、何が失敗しているのかはっきりしています。いったん '[HttpPost、ActionName(" _ PostCreate ")]'でアクションを装飾し、 'Ajax.BeginForm'を修正したところ、動作し始めました。 – Marco

+0

少なくとも2つの不要なデータベース呼び出しを行うことで、アプリケーションに不必要なコードがたくさんありパフォーマンスが低下します。私がチャンスを得たら、私はいくつかのコメントで答えを更新します。 –

+0

私はすべて(よく、ほとんどの)欠点を十分に認識しています。私は循環参照について頭を悩ましていました。コードは、Visual Studioのデフォルトのmvcテンプレートであり、その後、モデルとDALを追加して、私の主旨を示しました。 (これは70-486コースがAjaxをどのように実証しているかを実際に確認しています。 – Marco

関連する問題