Why does PartialView keep calling itself?

I tried to create a small demo in which the article contains a few comments. In the presentation of product details, comments should be made in a partial presentation. The partialView itself contains another partial view for adding a new comment.

When I try to add another comment, I get an InsufficientExecutionStackException because the action in the controller keeps calling itself. Why is this happening?

(If someone has course material, a similar example should be in module 9 in course 70-486 of Msft, which I am trying to build.)

Edit: Full code is on github

Edit2: Fixed fetching on Github. As Stephen Myukke noted, the fact that both the GET and POST methods have the same name causes a circular reference. Before more people point out that there are no DI and View models, and re-submitting all comments is suboptimal: Yes, I know, and no, these things were nothing that I wanted to accomplish. It was just a small demo.

Controller:

 [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); } 

the corresponding line in the Details.cshtml file for the article:

 @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> } 
+5
source share
1 answer

To explain what happens, you have a form that sends you the _CreateCommentForArticle() method, which then displays a partial _GetCommentsForArticle.cshtml , which in turn includes @Html.Action("_CreateCommentForArticle", ...) .

In the original GET method for Details() view will display correctly, but when you submit the form, the current request for the _GetCommentsForArticle page is [HttpPost] , so @Html.Action() will look for [HttpPost] (not the [HttpGet] method). That [HttpPost] in turn displays the partial expression _GetCommentsForArticle.cshtml and again calls the _CreateCommentForArticle() POST method, which displays the partial and _GetCommentsForArticle.cshtml until the memory shortage is over and an exception is thrown.

You can solve this problem by changing the name of the POST method, for example

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

and change the shape to fit

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

Source: https://habr.com/ru/post/1260231/


All Articles