ASP.NET MVC2:视图,视图模型和发布请求

时间:2010-11-27 03:36:52

标签: asp.net-mvc asp.net-mvc-2

我无法在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的单个实例从控制器传递到视图,然后返回控制器吗?”

1 个答案:

答案 0 :(得分:1)

我认为你做得很好。

您正在考虑尚未遇到的问题,当填充表单的数据与将要发布的数据大不相同时, 。这里“获取”视图模型是“后”视图模型的子集,因此使用一个视图模型很好,但如果“获取”的数据和“发布”的数据差别很大,则可以使用两个不同的视图模型如:

public class GetReplyFromViewModel  //...
public class PostReplyFromViewModel //...

但我建议不要这样做,除非两个视图模型都非常不同,而且要求自己的视图模型非常复杂。

要记住的一件重要事情:仅因为视图强类型化以输入'A'并不意味着post方法中参数的类型不能是'B'类型。

  • 视图的类型将简单地确定视图中的编译/智能感知以及创建视图时视图的类型检查。
  • post方法参数的类型将仅使用MVC Model Binding将发布的HTTP表单转换为您指定的类型。

换句话说,您的观点类型可能只是

<%@ Page Title="" ... Inherits="System.Web.Mvc.ViewPage<int>" %> 

如果您愿意,整个Model变量只是ThreadId,如果您的html字段命名正确,则post方法仍然可以使用相同的参数。

但同样,在这种特殊情况下,我认为目前的实施情况还不错。