C# 如何使用FormMethod.Post将内部类列表项添加到ViewModel中?
我知道有很多关于C# 如何使用FormMethod.Post将内部类列表项添加到ViewModel中?,c#,asp.net-mvc,razor,partial-views,actionresult,C#,Asp.net Mvc,Razor,Partial Views,Actionresult,我知道有很多关于@Html.Partial,@Html.RenderPartial,甚至使用@Html.Action与[ChildActionOnly]和PartialView()一起使用,但我的问题有点复杂,因为它涉及到FormMethod.Post,所以对于这个新手,任何帮助都将不胜感激。在解释我的问题之前,首先让我向您展示两个ViewModels: public class Article { public int ArticleId {get; set;}
@Html.Partial
,@Html.RenderPartial
,甚至使用@Html.Action
与[ChildActionOnly]
和PartialView()一起使用
,但我的问题有点复杂,因为它涉及到FormMethod.Post
,所以对于这个新手,任何帮助都将不胜感激。在解释我的问题之前,首先让我向您展示两个ViewModels:
public class Article
{
public int ArticleId {get; set;}
public int UserId {get; set;}
public virtual ICollection<Comment> Comments {get; set;}
//...
}
public class Comment
{
public Comment(int AId, int UId)
{
UserId = UId;
ArticleId = AId;
Content = "";
//...
}
public int CommentId {get; set;}
public int ArticleId {get; set;}
public int UserId {get; set;}
//...
}
下面是Detail.cshtml的部分以及我尝试过的选项:
@Html.Action("AddComment", new { AId = Model.ArticleId, UId = WebSecurity.CurrentUserId })
以下是GET/POST控制器操作:
[HttpGet, ChildActionOnly]
ActionResult AddComment(int AId, int UId)
{
Comment comment = new Comment(AId, UId);
return PartialView("_AddPostPartial", comment);
}
[HttpPost,ActionName("Post")]
public ActionResult AddComment(Comment comment)
{
if (ModelState.IsValid)
{
unitOfWork.ArticleRepository.InsertComment(comment);
RedirectToAction("Details", "Article", new { id = comment.ArticleId });
}
return PartialView("_AddPostPartial", comment);
}
问题是当我调试应用程序时,HttpGet中的注释不包含两个int的值。我以为Comment对象会在堆上,但它说它是空的。有人能给我指出正确的方向吗?我知道Ajax和JSON最终将是我使用的解决方案,但我仍然需要在之前让这些操作正常工作。提前谢谢!请尽可能批评:-)
*注意:我想知道我是否需要PartialView是@Model.Comment
?我基本上可以传递从视图创建注释对象所需的参数,但不一定要有一种方法来使用表单在ViewModel中创建新对象,而这些对象不是主视图中ViewModel的实例吗?我也明白,我基本上是在使用[ActionName(“Post”)]在操作中调用相同的操作,因此我不喜欢这样做,因此我确信这是错误的。
所以是的,我是个白痴。我走开了几分钟,去了商店,然后回来想了想。自我提示:始终确保使用关键字
return
,即使在重定向到操作时也是如此!好的,我将与大家分享我是如何解决这个问题的,这样如果其他人对此有问题,他们就不会像我一样花上几个小时
以下是我在主视图(Details.cshtml)中对我的操作的调用:
以下是返回PartialView的控制器操作AddComment:
[HttpGet]
public ActionResult AddComment(int AId)
{
Comment comment = new Comment(AId, WebSecurity.CurrentUserId);
return PartialView("_AddPostPartial", comment);
}
注意:必须实例化ModelView对象并将其传递给局部视图
下面是_addPostPartialPartialView,它承载将实例化对象发布到服务器的表单。然后,我会将我的InsertComment(Comment Comment)调用到我的UoW中,UoW拥有我的所有存储库,您将在ActionResult帖子中看到:
@model BlogSite.Models.Comment
@using (Html.BeginForm("Post", "Article", FormMethod.Post)){
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.ArticleId)
<div id="post-area">
@Html.TextAreaFor(m => m.Content, new { @id = "comment", @class = "textarea", @name = "comment" })
</div>
<div id="post-info">
<input type="submit" value="Post" class="post-button" />
</div>
}
<script>
$("form").submit(function (event) {
$("textarea[name=comment]").val("");
});
</script>
[HttpPost]
public ActionResult Post(Comment comment)
{
if (ModelState.IsValid)
{
unitOfWork.ArticleRepository.InsertComment(comment);
return RedirectToAction("Details", "Article", new { id = comment.ArticleId });
}
return PartialView("_AddPostPartial", comment);
}
通过使用UnitOfWork,我确保将重新注入更新的注释
对于文章(例如ArticleId=5),此函数位于UnitOfWork中实例化的存储库中:
public void InsertComment(Comment comment)
{
// actual insert of comment into database
context.Comments.Add(comment);
Article article = context.Articles.Find(comment.ArticleId);
UserProfile commenter = context.Users.Find(comment.UserId);
// in-memory List for both User and Article
article.Comments.Add(comment);
commenter.Comments.Add(comment);
context.Entry(article).State = EntityState.Modified;
context.Entry(commenter).State = EntityState.Modified;
Save();
}
注意:我认为在用户和文章的虚拟列表中添加评论很重要。当我取出后两个添加项时,
return RedirectToAction(“Details”,“Article”,new{comment.ArticleId})没有呈现新的注释代码>这让我觉得他们在内存中创建了ER?我的实际文章和用户域模型都有ICollection注释{get;set;}
,所以可能这就是我需要这样做的原因。我认为在这种情况下使用接口会更好,但如果我错了,请纠正我 我已经编辑了你的标题。请看“”,其中的共识是“不,他们不应该”。谢谢约翰。试图适应SO规则。我已经使用它好几年了,但现在我试图成为一个贡献者,而不是一个旁观者,因为没有更好的地方可以解决问题。IMO将检查它并据此采取行动。非常感谢。
[HttpPost]
public ActionResult Post(Comment comment)
{
if (ModelState.IsValid)
{
unitOfWork.ArticleRepository.InsertComment(comment);
return RedirectToAction("Details", "Article", new { id = comment.ArticleId });
}
return PartialView("_AddPostPartial", comment);
}
public void InsertComment(Comment comment)
{
// actual insert of comment into database
context.Comments.Add(comment);
Article article = context.Articles.Find(comment.ArticleId);
UserProfile commenter = context.Users.Find(comment.UserId);
// in-memory List for both User and Article
article.Comments.Add(comment);
commenter.Comments.Add(comment);
context.Entry(article).State = EntityState.Modified;
context.Entry(commenter).State = EntityState.Modified;
Save();
}