我无法在ASP.NET MVC2中遵循良好的面向对象设计,我认为问题是对用户发布信息时ViewModels和Views应该如何交互的理解不足。
我已经实现了一个论坛,允许用户使用“回复”操作创建对线程的回复。我的ReplyViewModel包含threadId的int和回复内容的字符串。 Reply操作使用ThreadId创建ReplyViewModel,因此我们将知道用户正在回复哪个线程。回复视图是对ReplyViewModel的强类型,并且具有允许用户编辑模型内容的表单。然后,用户可以使用threadId作为参数发布到Reply操作。
它有效,但我不认为我这样做是正确的。每个帖子都涉及两个ReplyViewModel:一个包含threadId但是null内容,另一个包含内容但是为空的ThreadId。回复视图正在创建一个新的ReplyViewModel,我认为它应该只是编辑传递给视图的ReplyViewModel - 但我不知道如何。
这是视图的精简版本:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<mvcForum.ViewModels.ReplyViewModel>" %>
<%: Html.TextAreaFor(model=> model.content, new{TextMode="multiline", id="postbox"})%>
<input type="submit" value="Reply" />
如果这还不足以回答我的问题,那么这就是整个视图:http://pastebin.com/BFGL4p67
ViewModel实际上只是一个字符串(内容)和一个int(threadId)。
控制器:
[Authorize]
public ActionResult Reply(int id)
{
ReplyViewModel reply = new ReplyViewModel
{
ThreadId = id
};
return View(reply);
}
[HttpPost]
public ActionResult Reply(int id, ReplyViewModel model)
{
/**TODO: Catch when no user*/
var newPost = new ForumPost
{
UserId = (Guid)Membership.GetUser(User.Identity.Name).ProviderUserKey,
ThreadId = id,
postContent = model.content
};
db.AddToForumPosts(newPost);
db.SaveChanges();
return RedirectToAction("Index");
}
所以我的问题是“做我正在做的事情的最佳方法是什么?我可以使用ReplyViewModel的单个实例从控制器传递到视图,然后返回控制器吗?”
答案 0 :(得分:1)
我认为你做得很好。
您正在考虑尚未遇到的问题,当填充表单的数据与将要发布的数据大不相同时, 。这里“获取”视图模型是“后”视图模型的子集,因此使用一个视图模型很好,但如果“获取”的数据和“发布”的数据差别很大,则可以使用两个不同的视图模型如:
public class GetReplyFromViewModel //...
public class PostReplyFromViewModel //...
但我建议不要这样做,除非两个视图模型都非常不同,而且要求自己的视图模型非常复杂。
要记住的一件重要事情:仅因为视图强类型化以输入'A'并不意味着post方法中参数的类型不能是'B'类型。
换句话说,您的观点类型可能只是
<%@ Page Title="" ... Inherits="System.Web.Mvc.ViewPage<int>" %>
如果您愿意,整个Model
变量只是ThreadId
,如果您的html字段命名正确,则post方法仍然可以使用相同的参数。
但同样,在这种特殊情况下,我认为目前的实施情况还不错。