接上篇,我們下面通過HtmlFiledSet helper來展示何時使用EndView():
如果你用Asp.net已經有一段時間了,那使用Html.BeginForm helper來建立HTML form标簽的方式會讓你覺得有點怪.當你建立一個新的Asp.net mvc項目後,在View裡的ChangePassword.aspx會預設被建立,這個頁面使用了Html.BeginForm helper,下面是使用這個helper的代碼段:
<% using (Html.BeginForm()) { %>
<div>
<fieldset>
<legend>Account Information</legend>
<p>
<label for="currentPassword">Current password:</label>
<%= Html.Password("currentPassword") %>
<%= Html.ValidationMessage("currentPassword") %>
</p>
<label for="newPassword">New password:</label>
<%= Html.Password("newPassword") %>
<%= Html.ValidationMessage("newPassword") %>
<p> <label for="confirmPassword">Confirm new password:</label>
<%= Html.Password("confirmPassword") %>
<%= Html.ValidationMessage("confirmPassword") %>
<input type="submit" value="Change Password" />
</fieldset>
</div>
<% } %>
上面代碼中你會發現Html.BeginForm的使用和<%=Html.Password(“currentPassword”) %>的使用不盡相同,也就是Html.BeginForm在using語句中被調用,這點很有意思,讓我先來看看上面代碼段生成後的Html,如下:
<form
action="/Account/LogOn?ReturnUrl=%2fAccount%2fChangePassword"
method="post">
<div>
<fieldset>
<legend>Account Information</legend>
<p>
<label for="username">Username:</label>
<input id="username" name="username" type="text" value="" />
</p>
<label for="password">Password:</label>
<input id="password" name="password" type="password" />
<input id="rememberMe" name="rememberMe" type="checkbox" value="true" />
<input name="rememberMe" type="hidden" value="false" />
<label class="inline" for="rememberMe">Remember me?</label>
<input type="submit" value="Log On" />
</fieldset>
</div>
</form>
比較<%= Html.Password("currentPassword") %> 語句和Html.BeginForm所生成的HTML代碼你會發現password那段僅僅僅僅将調用password擴充方法變成對應的Html,而BeginForm調用HTML擴充方法來注入form的開始标簽,<form…>,和using語句結束時(“}”)注入标簽<./form>.這種方式十分友善,因為我們可以一方面使用view helper建立合适的form标簽,另一方面在form标簽内插入任何我們想插入的html.這種方法的工作原理是當你調用Html.BeginForm方法并傳回MvcForm類型的對象,這個對象在using語句中是以當對象被回收(譯者按:也就是Dispose)的時候,也就是執行到結尾的”<% } %>”時,關閉标簽</form>将會被寫入到View中.下面是Dispose方法的實作:
public void Dispose() {
Dispose(true /* disposing */);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (!_disposed) {
_disposed = true;
_httpResponse.Write("</form>");
}
我們用相似的方法來實作HtmlFieldSet:
從這篇文章附帶的代碼中有一個”DetailsClassic.aspx”頁面中,一些字段包含于fieldset元素中,具體代碼如下:
<fieldset class="details-field-group" name="Details">
<legend>Details</legend>
<ol>
<li>
<label for="FirstName">FirstName</label>
<span id="FirstName">
<%= Html.Encode(Model.FirstName) %></span>
</li>
<label for="LastName">LastName</label>
<span id="LastName"><%= Html.Encode(Model.LastName) %></span>
<label for="Email">Email</label>
<span id="Email"><%= Html.Encode(Model.Email) %></span>
<label for="Phone">Phone</label>
<span id="Phone"><%= Html.Encode(Model.Phone) %></span>
<label for="Gender">Gender</label>
<span id="Gender"><%= Html.Encode(Model.Gender) %></span>
</ol>
</fieldset>
如果能用一個view helper來建立下面所有的html标簽,那會惬意很多:
fieldset的開始标記
legend标簽
ol的開始标簽
ol的結束标簽
fieldset的結束标簽
如果能用view helper來處理這些,那上面那段代碼無疑會簡單很多,尤其再加上使用Html.Text标簽來代替上面的text域。讓我們開始做到這一點,首先建立一個實作IViewObject接口的類,命名為HtmlFieldSet類并繼承與AbstractHtmlViewObject,整個類的代碼附下:
public class HtmlFieldset : AbstractHtmlViewObject
{
private readonly string mTitle;
public HtmlFieldset(
ViewRequestContext requestContext, string name,
string title, object attributes)
: base(requestContext, name)
{
mTitle = title;
Attributes = attributes;
private TagBuilder FieldsetTag { get; set; }
private TagBuilder OlTag { get; set; }
public override void StartView()
HttpResponseBase httpResponse = RequestContext.HttpResponse;
FieldsetTag = new TagBuilder("fieldset");
// apply any Attributes passed in
if (Attributes != null)
{
FieldsetTag.MergeAttributes(new RouteValueDictionary(Attributes));
}
// The Name property should override any passed into the Attributes
FieldsetTag.MergeAttribute("name", Name, true);
httpResponse.Write(FieldsetTag.ToString(TagRenderMode.StartTag));
if (!string.IsNullOrEmpty(mTitle))
TagBuilder legendTag = new TagBuilder("legend");
legendTag.SetInnerText(mTitle);
httpResponse.Write(legendTag.ToString(TagRenderMode.Normal));
}
OlTag = new TagBuilder("ol");
httpResponse.Write(OlTag.ToString(TagRenderMode.StartTag));
public override void EndView()
httpResponse.Write(OlTag.ToString(TagRenderMode.EndTag));
httpResponse.Write(FieldsetTag.ToString(TagRenderMode.EndTag));
這個類的實作和其它的view對象沒什麼不同,除了EndView方法,在這裡我們需要EndView方法來生成必須的結束标記。當然我們也可以使用EndView來生成任何需要的HTML,在這裡我們僅是用它生成結束标記。
-------------------------------------------
待續…
原文連結:http://mvcviewhelpers.codeplex.com/
translated by CareySon
分類: Asp.net MVC
本文轉自CareySon部落格園部落格,原文連結:http://www.cnblogs.com/CareySon/archive/2010/01/07/1640987.html,如需轉載請自行聯系原作者