ASP.NET MVC - 使用相同的表单来创建和编辑

ias*_*ons 42 forms asp.net-mvc

什么是创建用于创建新模型和编辑现有模型的表单的最佳实践方法?

是否有人可以指导我的教程?

Mar*_*nze 37

NerdDinner真正展现出自己的方式.

Create.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Models.Dinner>" MasterPageFile="~/Views/Shared/Site.Master"  %>
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Host a Nerd Dinner
</asp:Content>
<asp:Content ID="Create" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Host a Dinner</h2>
    <% Html.RenderPartial("DinnerForm"); %>
</asp:Content>
Run Code Online (Sandbox Code Playgroud)

Edit.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Models.Dinner>"
    MasterPageFile="~/Views/Shared/Site.Master" %>
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Edit: <%:Model.Title %>
</asp:Content>
<asp:Content ID="Edit" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Edit Dinner</h2>
    <% Html.RenderPartial("DinnerForm"); %>
</asp:Content>
Run Code Online (Sandbox Code Playgroud)

DinnerForm.ascx

<%@ Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NerdDinner.Models.Dinner>" %>
<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>
<% Html.EnableClientValidation(); %>
<%: Html.ValidationSummary("Please correct the errors and try again.") %>
   <% using (Html.BeginForm())
      { %>
   <fieldset>
       <div id="dinnerDiv">
           <%:Html.EditorForModel() %>
           <p>
               <input type="submit" value="Save" />
           </p>
       </div>
       <div id="mapDiv">
           <%: Html.EditorFor(m => m.Location) %>
       </div>
   </fieldset>
   <% } %>
Run Code Online (Sandbox Code Playgroud)

考虑到此表单正在使用Html.EditorForModel(),这是一种用于一次生成所有字段的创新方法,您必须在使用它之前研究它的缺点.但是,您可以轻松地使用示例的其余部分将您的常用表单与创建和编辑视图分开.

最后,如果您有兴趣,可以在这里查看控制器代码.


E R*_*cki 11

Scott Gu将展示自己的方式

  • 在哪里解释?我在文章中浏览了3到4次,但找不到答案. (4认同)
  • 你不要为这两种形式使用单一形式,因为它们本质上是两种截然不同的动作.您可以删除创建表单的字段,将它们放在局部视图中,然后在创建表单和编辑表单中引用该部分. (2认同)

Cra*_*ntz 8

不要使用相同的控制器操作.新= HTTP PUT; edit = HTTP POST,这是两个不同的东西.但是,这两个动作可以并且应该在同一个控制器上.

我喜欢将用户控件用于常用功能(例如,编辑器),并将其包含在特定于操作的视图中,以用于只应出现在新内容或编辑内容中的内容,而不是两者.

  • 动词与CRUD的关联在这里令人困惑,因为没有直接存在这种相关性(讨论:http://reinout.vanrees.org/research/phd/various-stuff/getputpostdelete和http://www.elharo.com/blog/软件开发/ Web开发/ 2005/12/08 /后VS看跌/) (5认同)
  • 如果你不区分使用HTTP动词,那么使用相同的动作是完全合理的.否则会有很多重复.您只需将ID作为参数,首先获取非零值,等等. (3认同)

Dmi*_*sky 6

假设

  1. 这对于用户在浏览器中查看不同操作的不同URL很有用.例如'/ pages/create'和'/ pages/edit/1'.

  2. 这对于开发人员来说只有一个动作+视图对来创建和编辑页面是很好的,因为它们通常非常相似.(另外,每个实体都有一个控制器.)

默认路由注册为"{controller}/{action}/{id}"我们可以之前再添加两条规则:

{controller}/create(应该指向'CreateOrEdit'动作)

{controller}/edit/{id}(也应该指向'CreateOrEdit'动作)

我们现在可以拥有这样的东西:

public static void RegisterRoutes(RouteCollection routes)
{
  routes.MapRoute(
    name: "Create",
    url: "{controller}/create",
    defaults: new { controller = "Default", action = "CreateOrEdit" }
  );

  routes.MapRoute(
    name: "Edit",
    url: "{controller}/edit/{id}",
    defaults: new { controller = "Default", action = "CreateOrEdit" }
  );

  routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
  );
}
Run Code Online (Sandbox Code Playgroud)

因此,现在创建和编辑请求都将由"CreateOrEdit"操作处理.其他人将采用默认方式.

接下来我们应该做的是在我们的控制器中为HttpGet和HttpPost添加'CreateOrEdit'动作:

[HttpGet]
public ActionResult CreateOrEdit(int? id)
{
  return this.View(new CreateOrEditViewModelBuilder(this).Build(id));
}

[HttpPost]
public ActionResult CreateOrEdit(CreateOrEditViewModel ?reateOrEditViewModel)
{
  if (this.ModelState.IsValid)
  {
    Page page = new CreateOrEditViewModelMapper(this).Map(?reateOrEditViewModel);

    if (?reateOrEditViewModel.Id == null)
      this.UnitOfWork.GetRepository<IPageRepository>().Create(page);

    else this.UnitOfWork.GetRepository<IPageRepository>().Edit(page);

    this.UnitOfWork.Save();
    return this.RedirectToAction("Index");
  }

  return this.View(?reateOrEditViewModel);
}
Run Code Online (Sandbox Code Playgroud)

最后我们要添加名为'CreateOrEdit'的视图.我们可以使用'this.Model.Id == null'来了解我们是创建还是编辑.

结果

现在我们没有重复的代码,可以有这样的明显网址:

/ pages(查看所有页面)

/ pages/create(创建新页面)

/ pages/edit/1(编辑现有页面)

/ pages/delete/1(删除现有页面)

我希望它会帮助别人!