Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
157 views
in Technique[技术] by (71.8m points)

c# - Why does the PartialView keep calling itself?

I've tried to set up a small demo, in which an article has multiple comments. The article details view, should render the comments in a partial view. The partialView itself contains another partial view for adding a new comment.

When I try to add another comment I receive a InsufficientExecutionStackException, because the action in the controller keeps calling itself. Why does this happen?

(If somebody has the course material at hand. A similar example should be at module 9 in the 70-486 course from Msft; that's what I trying to build.)

Edit: The full code is on github

Edit2: The sample on Github has been fixed. As Stephen Muecke pointed out, the fact, that both the GET and POST method hat the same names was causing the circular reference. Before any more people point out, that DI and View Models are missing and that re-rendering all comments is sub-optimal: Yes I am aware and no, those things were nothing, that I wanted to accomplish. This was just a quick n dirty 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);
}

relevant line in the Details.cshtml for 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>
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To explain what is happening, you have a form that posts to you _CreateCommentForArticle() method, which then renders your _GetCommentsForArticle.cshtml partial which in turn includes @Html.Action("_CreateCommentForArticle", ...).

In the initial GET method for Details() the view will be rendered correctly, but when you submit the form, the current request for the _GetCommentsForArticle page is a [HttpPost] method, so @Html.Action() will look for a [HttpPost] method (not the [HttpGet] method). That [HttpPost] in turn renders the _GetCommentsForArticle.cshtml partial and again calls the _CreateCommentForArticle() POST method which renders the _GetCommentsForArticle.cshtml partial and so on until you run out of memory and the exception is thrown.

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

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

and modify the form to suit

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...