【问题标题】:Change method call order when form is posted in MVC在 MVC 中发布表单时更改方法调用顺序
【发布时间】:2012-11-19 22:59:27
【问题描述】:

这里有点奇怪。我有一个博客,它是另一个“涉足 MVC”项目,它将突出我们新 Intranet 的好处。我有一个典型的博客文章页面,其中包含文章、cmets 和用于针对给定文章提交 cmets 的表单。

我有一个字符串类型的主视图(“Post”),其中包含文章内容,然后是两个 Html.RenderAction 方法;一个获取 cmets,一个通过表单添加 cmets。

我的问题是,当发表评论时,我的 GetComments 方法在 AddComment 之前调用,因此当刷新页面时,尽管新评论已添加到数据库中,但它是不可见的。快速 F5 确认了这一点。我知道 GetComments 是首先被调用的,因为它是在视图中首先声明的,但我不确定如何告诉视图在获取之前进行添加。

这是我的代码:

控制器:

public ActionResult AddComment()
    {
        return PartialView("AddComment");
    }

    [HttpPost]
    public ActionResult AddComment(Comment comment)
    {
        comment.DateSubmitted = DateTime.Now;
        db.Comments.Add(comment);
        db.SaveChanges();
        return PartialView(comment);
    }

    public ActionResult GetComments(int articleid)
    {
        var comments = db.Comments.Where(c => c.ArticleID == articleid).ToList();
        return PartialView(comments);
    }

发布视图

@model IntranetBlog.Models.Article

@{
ViewBag.Title = "Post";
}

 <div class="row">
<div class="span12">
    <h3>@Html.DisplayFor(modelItem => Model.Title)</h3>
    <small>by Ruth Barlow on @Html.DisplayFor(modelItem => Model.DateCreated)</small>
    @if (Model.Image != null)
    {
        <p>
            <img src="@Url.Action("GetImage", "Home", new { articleID = Model.ArticleID     })" alt="" width="150" height="150" />
        </p>
    }

    <div>
        @Html.DisplayFor(modelItem => Model.Body)
    </div>
    <small>Posted under @Html.DisplayFor(modelItem => Model.Category.Name)</small>
</div>
<div class="span12">
    @{
        Html.RenderAction("GetComments", "Home", new { articleID = Model.ArticleID });
    }
</div>
<div class="span12">
    @{
        Html.RenderAction("AddComment", "Home", new { articleID = Model.ArticleID });
    }
</div>
</div>

GetComments 部分:

@model IEnumerable<IntranetBlog.Models.Comment>

@if (Model.Any())
{
<h3>What you're saying</h3>
foreach (var item in Model)
{
    <div>
        Comment: @Html.DisplayFor(modelItem => item.Body)
    </div>
    <div>
        Submitted by: @Html.DisplayFor(modelItem => item.SubmittedBy) 
on @Html.DisplayFor(modelItem => item.DateSubmitted)
    </div>
    <hr />
}
}
else
{
  <p>There are no comments for this post. Why not add one?</p>
}

添加评论部分

@model IntranetBlog.Models.Comment

@using (Html.BeginForm())
{
<h3>Why not leave us a comment?</h3>
@Html.ValidationSummary()
<fieldset>
    <div class="editor-label">
        @Html.LabelFor(model => model.Body)
    </div>
    <div class="editor-field">
        @Html.TextAreaFor(model => model.Body, 20, 20, null)
        @Html.ValidationMessageFor(model => model.Body)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.SubmittedBy)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.SubmittedBy)
        @Html.ValidationMessageFor(model => model.SubmittedBy)
    </div>

    <p>
        <input type="submit" value="Add comment" id="AddComment" class="btn btn-    primary" />
    </p>
</fieldset>
}

希望这是有道理的。 提前致谢。

【问题讨论】:

    标签: asp.net-mvc partial-views


    【解决方案1】:

    诀窍是使用Html.Action 而不是Html.RenderAction 这将允许您将结果存储在变量中,然后将其添加到需要显示的位置。

    这将允许您以所需的逻辑顺序生成 PartialView,同时以其他顺序显示它们。

    有关如何操作的快速示例,请参阅此帖子:https://stackoverflow.com/a/13301057/971693

    【讨论】:

    • 谢谢你 - 这是一个绝妙的技巧,但我觉得不应该花费我一天中最好的时间来弄清楚!
    • 有时这是我们监督最多的小事。
    【解决方案2】:

    我会向您建议一种稍微不同的方法。考虑使用 Ajax.BeginForm 来提交评论,而不是使用 Html.BeginForm。作为 ajax,它将具有更好的性能,因为它允许您的方法只返回 cmets,以便您可以替换旧的 cmets,或者甚至只是新添加的 cmets,以便将其添加到列表的底部。话虽如此,这个解决方案确实依赖于使用 javascript,最好是 jquery-unobtrusive-ajax 来工作并呈现看起来不错的客户端代码。由于 AjaxOptions 类内置了一些功能强大但易于使用的选项,因此您无需了解 javascript 即可使用此方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多