创建用于创建新模型和编辑现有模型的表单的最佳实践方法是什么?
有没有人可以指导我的教程?
答案 0 :(得分:37)
NerdDinner将真正显示出来。
<%@ 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>
<%@ 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>
<%@ 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>
<% } %>
考虑到此表单正在使用Html.EditorForModel()
,这是一种用于一次生成所有字段的创新方法,您必须在使用它之前研究它的缺点。但是,您可以轻松地将示例的其余部分与创建和编辑视图分开。
最后,如果您有兴趣,可以查看controller code here。
答案 1 :(得分:11)
答案 2 :(得分:8)
不要使用相同的控制器操作。新= HTTP PUT; edit = HTTP POST,这是两个不同的东西。但是,这两个动作都可以并且应该在同一个控制器上。
我喜欢将用户控件用于常用功能(例如编辑器),并将其包含在特定于操作的视图中,以用于只应出现在新内容或编辑内容中的内容,而不是两者。
答案 3 :(得分:5)
<强>假设强>
这对于用户在浏览器中查看不同操作的不同URL很有用。例如'/ pages / create'和'/ pages / edit / 1'。
这对于开发人员来说只有一个动作+视图对来创建和编辑页面是有好处的,因为它们通常非常相似。 (另外,每个实体最好有一个控制器。)
<强>解决方案强>
默认路线注册为“{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 }
);
}
所以现在创建和编辑请求都将由'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);
}
最后我们要添加名为'CreateOrEdit'的视图。我们可以使用'this.Model.Id == null'来了解我们是否创建或编辑。
<强>结果强>
现在我们没有重复的代码,可以有这样的明显网址:
/ pages(查看所有页面)
/ pages / create(创建新页面)
/ pages / edit / 1(编辑现有页面)
/ pages / delete / 1(删除现有页面)
我希望它会帮助别人!
答案 4 :(得分:1)
它可能(应该是IMO)一个控制器但不同的控制器动作。还要确保您具有与适当操作相关联的正确HTTP谓词。按照E Rolnicki发布的教程,你就可以了!
快乐编码!!
答案 5 :(得分:1)
这并非总是最佳做法,因为它取决于具体情况,这是我如何做到的
1 / 我结合了用于创建和编辑的控制器操作
public PartialViewResult Creedit(string id = null)
{
if (id == null)
{
// Create new record (this is the view in Create mode)
return PartialView();
}
else
{
// Edit record (view in Edit mode)
Client x = db.ClientSet.Find(id);
if (x == null) { return PartialView("_error"); }
// ...
return PartialView(x);
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Creedit(Client x)
{
if (x.id == null)
{
// insert new record
}
else
{
// update record
}
}
2 / 我将编辑和创建视图合并到一个视图中我称之为Creedit
// if you need to display something unique to a create view
// just check if the Model is null
@if(Model==null){
}
所以我有1个视图和2个动作(1个帖子和1个获取),而不是2个视图和4个动作。
答案 6 :(得分:0)
我将表单本身放在用户控件中 - 比如Views / Shared / WidgetForm.ascx。我将所有表单字段放在此用户控件中,但不是表单标记本身。
视图,例如Views / Widgets / New.aspx和Views / Widgets / Edit.aspx,其中包含表单标签和所有“环境” - 填写表单,页面标题等的说明。然后它们在表单标记中包含用户控件。
用户控件只需一个Widget对象,并根据结果显示一个表单。因此,在新的Widget选项中设置合理的默认值变得很重要,但无论如何你都是这样做的,对吧? ;)
答案 7 :(得分:0)
我认为我的系统效果非常好。在我的共享视图中,我有两个通用形式,Edit.aspx和New.aspx
然后在我的特定视图文件夹中,我有一个名为EditItems.ascx的控件
在我的编辑表单中,我有用于编辑的表单标签和特定按钮,在新表单中,我有新的表单标签和特定按钮。在每个我有Html.RenderPartial(“EditItems.ascx”)
这样您的用户控件可以强类型,但您重复使用编辑和新页面的外观。
现在在某些情况下,您的新网页可能与“编辑”页面的布局不同。在这种情况下,只需将“Edit.aspx”添加到您的特定视图文件夹。
我发现这给了我最好的重用组合,同时在我需要时仍允许完全自定义。至于控制器动作,是的,它们应该是单独的动作。
答案 8 :(得分:0)
如果实体有某种内部私钥(例如“id”成员始终> 0),您可以使用/ Edit / 0而不是/ Create
答案 9 :(得分:0)
我使用类似
的东西[HttpGet]
public ActionResult EntityEdit(Guid id)
{
return View();
}
和
[HttpGet]
public ActionResult EntityCreate()
{
return View("EntityEdit");
}
这似乎工作正常。