ASP.net MVC 2.0使用相同的表单进行添加和编辑

时间:2011-02-16 23:33:28

标签: c# asp.net-mvc entity-framework asp.net-mvc-2 entity-framework-4

我想使用相同的视图来编辑博客文章和添加博客文章。但是,我遇到了ID的问题。添加博客文章时,我不需要发布ID值。当模型绑定将表单值绑定到控制器中的BlogPost对象时,它将在实体框架实体中自动生成ID。

当我编辑博客文章时,我需要一个隐藏的表单字段来存储ID,以便它伴随下一个表单帖子。以下是我现在的观点。

<% using (Html.BeginForm("CommitEditBlogPost", "Admin"))
       { %>
            <% if (Model != null)
               { %>
                    <%: Html.HiddenFor(x => x.Id)%>
            <% } %>
            Title:<br />
            <%: Html.TextBoxFor(x => x.Title, new { Style = "Width: 90%;" })%>
            <br />
            <br />
            Summary:<br />
            <%: Html.TextAreaFor(x => x.Summary, new { Style = "Width: 90%; Height: 50px;" }) %>
            <br />
            <br />
            Body:<br />
            <%: Html.TextAreaFor(x => x.Body, new { Style = "Height: 250px; Width: 90%;" })%>
            <br />
            <br />
            <input type="submit" value="Submit" />
    <% } %>

现在检查模型是否为NULL是一个很好的方式来了解我是在编辑博客文章还是添加一个博客文章,因为当我添加一个博客文章时,它将为null,因为它尚未创建。当出现错误且实体无效时,会出现问题。当控制器在无效模型之后呈现表单时,Model != null评估为false,即使我们正在编辑帖子并且显然存在模型。如果我在添加帖子时为ID呈现隐藏的输入字段,我会收到一条错误,指出该ID不能为空。

感谢任何帮助。

编辑:我接受了OJ对这个问题的回答,但是我发现了让我感到愚蠢的事情,我想分享它,以防万一有人遇到类似的问题。添加/编辑博客的页面甚至不需要id的隐藏字段。原因是当我去添加博客时,我对这个相对URL BlogProject/Admin/AddBlogPost

进行了GET

此URL不包含ID,操作方法只是呈现页面。添加博客帖子时,该页面会对同一URL执行POST操作。传入的BlogPost实体由模型绑定填充,并具有在保存更改期间由EF生成的空ID。

现在,当编辑博客帖子时,网址为BlogProject/Admin/EditBlogPost/{Id} 此URL包含博客文章的ID,并且由于页面回发到完全相同的URL,因此id与POST一起执行编辑的操作方法。

我遇到的唯一问题是操作方法不能具有相同的签名。

[HttpGet]
public ViewResult EditBlogPost(int Id)
{

}

[HttpPost]
public ViewResult EditBlogPost(int Id)
{

}

如果您尝试使用上述两种方法,编译器会对您大喊大叫。在执行没有动作或控制器参数的Html.BeginForm()时,将非常方便地回发Id。因此,我只是修改了参数以包含FormCollection,而不是更改POST方法的名称。像这样:

[HttpPost]
public ViewResult EditBlogPost(int Id, FormCollection formCollection)
{
     // You can then use formCollection as the IValueProvider for UpdateModel()
     // and TryUpdateModel() if you wish. I mean, you might as well use the
     // argument since you're taking it.
}

formCollection变量通过模型绑定填充,默认情况下Request.Form的内容相同。您不必将此集合用于UpdateModel()TryUpdateModel(),但我之所以这样做,我觉得这个集合毫无意义,因为它只是让方法签名与其GET不同对应物。

感谢帮帮!如果您找到更好的方法来完成这项工作,请告诉我们。我唯一不满的部分是接受一个不必要的变量来使方法签名不同。

2 个答案:

答案 0 :(得分:2)

我在项目中所做的工作如下:

  • 有一个单独的操作和视图供编辑和添加
  • 传递编辑网址中对象的ID而不是隐藏字段
  • 使用对象的共享编辑器模板,以避免两次编写相同的样板代码

如果您正确执行此操作,添加和编辑视图将非常小。

答案 1 :(得分:2)

一些选择:

  • 制作Id媒体资源Nullable,然后查看HasValue
  • mode添加某种ViewData指示符,并根据值显示隐藏字段。
  • 将表单正文放在局部视图中,并将其包含在两个不同的视图中,一个带有隐藏字段,另一个没有隐藏字段。