使用ASP.NET MVC,如何最好地避免同时编写"添加视图"和"编辑视图"?

时间:2020-03-05 18:41:17  来源:igfitidea点击:

"添加"视图和"编辑"视图通常非常相似,因此不必编写2个视图。随着应用程序的发展,我们将对两者进行相同的更改。

但是,通常会有细微的差异。例如,添加一个字段后,该字段可能是只读的;如果该字段是DropDownList,则在ViewData中不再需要该List。

因此,我是否应该创建一个包含两个视图的所有信息的视图数据类,其中根据我们执行的操作,某些属性为null?
我应该将该操作作为枚举包含在视图数据中吗?
我是否应该用<%if(ViewData.Model.Op == Ops.Editing){%>包围所有细微的差异?

或者,还有更好的方法?

解决方案

回答

我不希望视图变得过于复杂,到目前为止,我倾向于将单独的视图用于"编辑"和"添加"。我使用一个用户控件来存储公共元素,以避免重复。这两个视图将以相同的ViewData为中心,并且我在数据上有一个标记,用于说明该对象是新对象还是现有对象。

这没有比我们所规定的更为优雅,因此我想知道Django或者Rails的家伙是否可以提供任何输入。

我喜欢asp.net mvc,但它仍在成熟中,仍然需要添加更多糖来消除创建网站的麻烦。

回答

我个人只是喜欢在视图中使用if / else。它可以帮助我立即查看正在发生的所有事情。

如果我们想避免使用标签汤,建议我们创建一个辅助方法。

<%= Helper.ProfessionField() %>

string ProfessionField()
{
    if(IsNewItem) { return /* some drop down code */ }
    else { return "<p>" + _profession+ "</p>"; }        
}

回答

真的很容易。假设我们正在编辑博客文章。

这是我们进行新操作/修改的2个操作:

public class BlogController : Controller
{
   public ActionResult New()
   {
      var post = new Post();
      return View("Edit", post);
   }

   public ActionResult Edit(int id)
   {
      var post = _repository.Get(id);
      return View(post);
   }

   ....

}

这是视图:

<% using(Html.Form("save")) { %>
<%= Html.Hidden("Id") %>

<label for="Title">Title</label>
<%= Html.TextBox("Title") %>

<label for="Body">Body</label>
<%= Html.TextArea("Body") %>

<%= Html.Submit("Submit") %>
<% } %>

这是视图提交到的"保存"操作:

public ActionResult Save(int id, string title, string body)
{
   var post = id == 0 ? new Post() : _repository.Get(id);
   post.Title = title;
   post.Body = body;

   _repository.Save(post);

   return RedirectToAction("list");
}

回答

我们可以指定CustomViewData类并在此处传递参数。

public class MyViewData {
    public bool IsReadOnly { get; set; }
    public ModelObject MyObject { get; set; }
}

并且两个视图都应实现此ViewData。
因此,我们可以使用提供的IsReadOnly属性来管理UserControl结果。

当控制器使用它时,我们可以对其进行单元测试,并且视图没有实现,因此我们可以遵守MVC原则。