创建、更新、删除记录
我们已经介绍了控制器和视图,已经知道如何实现数据列表和详细信息的显示。接下来,我们进一步扩展DinnersController类实现编辑、创建和删除Dinners记录。
DinnersController处理URL请求
之前我们添加了2个action方法到DinnersController控制器,实现支持如下2个URL:/Dinners和/Dinners/Details/[id]。
现在,我们增加更多的action方法,实现如下3个URL地址:
/Dinners/Edit/[id]
/Dinners/Create
/Dinners/Delete/[id]
这些URL分别支持编辑已存在的Dinners,创建新的Dinners和删除Dinners。
我们将同时支持HTTP GET和HTTP POST方法访问这些新的URL地址。HTTP GET对这些URL地址的请求将显示初始的HTML视图(edit将显示Dinner数据;create 将显示一个空白的窗口;delete则显示一个确认对话框)。HTTP POST对这些URL的请求将保存/更新/删除DinnerRepository的Dinner数据。
下面开始实行edit方案。
实现HTTP-GET 编辑Action方法
我们首先实现edit action方法的HTTP GET动作。在访问/Dinners/Edit/[id]地址时,该方法将被调用。实现代码如下:
//
// GET: /Dinners/Edit/2
public ActionResult Edit(int id)
{
Dinner dinner = dinnerRepository.GetDinner(id);
return View(dinner);
}
上述代码使用DinnerRespository检索一个Dinner对象,接着在一个视图模板中程序Dinner对象。因为在View() 辅助方法中没有显式传入视图的名称,因此它将基于惯例,使用默认的视图模板:/Views/Dinners/Edit.aspx。
现在,我们开始创建视图模板,步骤与前面创建视图模板一样。在DinnersController的Edit action方法中点击鼠标右键,选择Add View菜单项。在弹出的Add View对话框,设置View data class为NerdDinner.Models.Dinner,表示将传入Dinner对象(Model)给视图模板。同时,设置View content为Edit,表示将创建一个初始的编辑模板。如下图所示:
在点击Add按钮后,Visual Studio自动在\Views\Dinners目录中创建一个新的Edit.aspx 视图模板文件,并自动在VS 编辑器中打开,提供一个初始的Edit模板的实现。
下面我们对默认生成的Edit视图进行一些更新,代码如下(删除了一些不想公开的属性):
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Edit: <%= Html.Encode(Model.Title) %>
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2>Edit Dinner</h2>
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm()) {%>
<fieldset>
<p>
<label for="Title">标题:</label>
<%= Html.TextBox("Title", Model.Title) %>
<%= Html.ValidationMessage("Title", "*") %>
</p>
<p>
<label for="EventDate">事件日期:</label>
<%= Html.TextBox("EventDate", String.Format("{0:g}", Model.EventDate)) %>
<%= Html.ValidationMessage("EventDate", "*") %>
</p>
<p>
<label for="Description">描述:</label>
<%= Html.TextBox("Description", Model.Description) %>
<%= Html.ValidationMessage("Description", "*") %>
</p>
<p>
<label for="HostedBy">主持者:</label>
<%= Html.TextBox("HostedBy", Model.HostedBy) %>
<%= Html.ValidationMessage("HostedBy", "*") %>
</p>
<p>
<label for="ContactPhone">联系电话:</label>
<%= Html.TextBox("ContactPhone", Model.ContactPhone) %>
<%= Html.ValidationMessage("ContactPhone", "*") %>
</p>
<p>
<label for="Address">地址:</label>
<%= Html.TextBox("Address", Model.Address) %>
<%= Html.ValidationMessage("Address", "*") %>
</p>
<p>
<label for="Country">国家:</label>
<%= Html.TextBox("Country", Model.Country) %>
<%= Html.ValidationMessage("Country", "*") %>
</p>
<p>
<label for="Latitude">维度:</label>
<%= Html.TextBox("Latitude", String.Format("{0:F}", Model.Latitude)) %>
<%= Html.ValidationMessage("Latitude", "*") %>
</p>
<p>
<label for="Longitude">经度:</label>
<%= Html.TextBox("Longitude", String.Format("{0:F}", Model.Longitude)) %>
<%= Html.ValidationMessage("Longitude", "*") %>
</p>
<p>
<input type="submit" value="保存" />
</p>
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
现在运行应用程序,请访问/Dinners/Edit/2 网址,将看到如下的页面:
上述页面的HTML脚本如下所示,就是一个标准的HTML-有一个<form>元素。在点击Save保存按钮后,向/Dinners/Edit/2 执行HTTP POST动作。其中HTML元素 - <input type=”text” />元素用来展示可编辑的文本框。
Html.BeginForm() 和 Html.TextBox() HTML辅助方法
Edit.aspx视图模板使用了一些HTML辅助方法:Html.ValidationSummary(),Html.BeginForm(),Html.TextBox(),和Html.ValidationMessage()等等。处理生成HTML脚本外,这些辅助方法还提供了内置的错误处理和验证支持。
Html.BeginForm() 辅助方法
Html.BeginForm() 辅助方法用来输出HTML <form>元素。在Edit.aspx视图模板中,你会发现我们使用了C#的using 语句。左括号{ 表示开始<form>元素,右括号 } 表示结束</form> 元素:
<% using (Html.BeginForm()) { %>
<fieldset>
<!-- Fields Omitted for Brevity -->
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
如果你认为使用using语句并不直观,你也可以使用Html.BeginForm() 和 Html.EndForm() 组合,示例代码如下:
<% Html.BeginForm(); %>
<fieldset>
<!-- Fields Omitted for Brevity -->
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% Html.EndForm(); %>
调用不传参数的Html.BeginForm() 方法将输出一个form元素,和HTTP-POST方法和当前请求的URL地址,这就是为什么Edit视图生成如下 <form action=”/Dinners/Edit/1” method=”post”> 元素。当然,如果需要提交到不同的URL地址,我们可以传入显式的参数给Html.BeginForm() 方法。
Html.TextBox() 辅助方法
Edit.aspx视图使用Html.TextBox() 辅助方法输出<input type=”text” />元素:
<%= Html.TextBox("Title") %>
上面的Html.TextBox() 方法接收了仅仅一个参数 – 用来同时指定<input type=”text” />元素的id/name 属性,以及填充文本框值的Model属性。例如,传入的Dinner 对象的Title属性值为EntLib.com 开源ASP.NET论坛,因此Html.TextBox(“Title”)方法将输出 <input
id=”Title” name=”Title” type=”text” value=”EntLib.com 开源ASP.NET论坛” />。
另外,我们也可以使用Html.TextBox() 的第一个参数来指定元素的id/name属性值,并显式给第二个参数传递值。
<%= Html.TextBox("Title", Model.Title) %>
如果需要对输出结果进行格式化输出,则可以使用.NET 内置的String.Format() 静态方法。Edit.aspx视图模板使用这一方法来对EventDate 值进行格式化(DateTime类型),不显示秒信息:
<%= Html.TextBox("EventDate", String.Format("{0:g}", Model.EventDate)) %>
Html.TextBox() 方法的第三个可选参数可用来输出额外的HTML属性。如下代码显示如何对<input type=”text” />元素呈现额外的size=”30”和class=”mycssclass”属性。注意:这里为了避免冲突C#的关键字Class冲突,采用@前缀。
<%= Html.TextBox("Title", Model.Title, new { size=30, @class="myclass" } )%>
来自西北的狼!