我们在Asp.net
mvc的view开发过程中,如果不注意可能会写大量的重复的代码。这篇文章介绍3种方式重构View的代码,来减少View中的重复代码。
1、母板页
在Asp.net mvc中保留了母板页的使用,我们可以使用母板页对我们的站点进行布局。看下面母板页的代码:
<%@ Master Language="C#"
Inherits="System.Web.Mvc.ViewMasterPage"
%>
<!DOCTYPE html
PUBLIC
"-//W3C//DTD XHTML
1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title><asp:ContentPlaceHolder
ID="TitleContent"
runat="server"
/></title>
<link href="http://www.cnblogs.com/Content/Site.css"
rel="stylesheet"
type="text/css"
/>
</head>
<body>
<div class="page">
<div
id="header">
<div
id="title">
<h1>My
MVC Application</h1>
</div>
<div
id="logindisplay">
<%=
Html.Action("LogOnWidget",
"Account")
%>
</div>
<div
id="menucontainer">
<ul
id="menu">
<li><%=
Html.ActionLink("Home",
"Index",
"Home")%></li>
<li><%=
Html.ActionLink("Profiles",
"Index",
"Profile")%></li>
<li><%=
Html.ActionLink("About",
"About",
"Home")%></li>
</ul>
</div>
</div>
<div
id="main">
<asp:ContentPlaceHolder
ID="MainContent"
runat="server"
/>
<div
id="footer"></div>
</div>
</div>
</body>
</html>
My MVC Application
在Asp.net mvc中使用母板页和Web Form中类似,需要定义ContentPlaceHolder,加上使用一些常用的HTML标签进行布局。
当多个页面都有同样的内容的时候,使用母板页是非常有用的。
2、Partial
Partial类似于Web Form中的用户控件。用它来渲染成内容页,使用Partial最大的好处是这些代码段定义在View页面,而不是代码中。下面举例说明:
渲染partial非常简单,我们可以在父View中使用RenderPartial和Partial方法,Profiles的代码如下,在Profiles中使用RenderPartial渲染Profile。
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Profile>>"
%>
<h2>Profiles</h2>
<table>
<tr>
<th>Username</th>
<th>First
name</th>
<th>Last
name</th>
<th>Email</th>
</tr>
<% foreach (var profile
in Model) { %>
<%
Html.RenderPartial("Profile",
profile); %>
<% } %>
</table>
上面的代码,我将一个profile的List渲染成一个table。每一行定义了一个Partial,用来渲染成一行。即使内容页不能与其他View分享,在一个View中使用partial可以简化和减少HTML的标签数量。RenderPartial方法需要一个partial名字和一个Model参数。根据的partial名字用来搜索本地的partial文件,需遵循下面的规则:
1 \\.aspx and .ascx
2 \Shared\.aspx and .ascx
3 \\.aspx and .ascx
4 \Shared\.aspx and .ascx
这些搜索类似于根据view的name搜索view,也可以使用 渲染。Profile文件即可以是一个ASCX文件,如果必要也可以是一个aspx的文件。Profile的代码如下:
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<Profile>"
%>
<tr>
<td>
<%=
Html.ActionLink(Model.Username, "Show",
new{
username = Model.Username }) %>
</td>
<td><%= Model.FirstName%></td>
<td><%= Model.LastName%></td>
<td><%= Model.Email
%></td>
</tr>
我们在View中如下渲染Profiles:
<% Html.RenderPartial("Profiles",
Model); %>
渲染效果如下:
3、Child Action
Partial用来显示已经存在Model的信息时非常方便的。但是有时候View上显示的数据源自其他Model。例如,登录控件可能会显示当前用户的名称和电子邮件,但该View的主体部分与用户关系不大。可以使用ViewDataDictionary来传递没联系的Model,但是我们可以使用Child
Action。对于在View中显示与主体没有多大关系的信息,这里介绍一下Child Action的使用。下面举例子说明。
在模板页中显示当前的用户信息,当用户登录之后,显示用户名,邮箱之类的信息,当用户没有登录,给出登录的连接。在模板页中加入下面代码:
<div id="logindisplay">
<%=
Html.Action("LogOnWidget",
"Account")
%>
</div>
LogOnWidget的代码如下,ChildActionOnly确保只能通过RenderAction调用此方法。
[ChildActionOnly]
public
ViewResult LogOnWidget()
{
bool isAuthenticated = Request.IsAuthenticated;
Profile profile =
null;
if
(isAuthenticated)
{
var username = HttpContext.User.Identity.Name;
profile = _profileRepository.Find(username);
if
(profile == null)
{
profile = new
Profile(username);
_profileRepository.Add(profile);
}
return View(new LogOnWidgetModel(isAuthenticated,
profile));
用一个用户控件来显示这个Action的Model的信息,用户控件代码如下。
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl"
%>
<%@ Import Namespace="AccountProfile.Controllers"%>
<%
if
(Request.IsAuthenticated) {
%>
Welcome
<b><%= Html.Encode(Page.User.Identity.Name)
%></b>!
[
<%= Html.ActionLink("Log
Off",
"LogOff",
"Account")
%> | <%= Html.ActionLink("Profile",
"Show",
"Profile",
new
RouteValueDictionary(new
{ username = Html.Encode(Page.User.Identity.Name)
}), null)%>
]
<%
}
else
{
%>
[
<%= Html.ActionLink("Log
On",
"LogOn",
"Account")
%> ]
<%
}
%>
总结:本文阐述了三种方式来重构你View的代码,使用这三种方式可以大量减少View层重复出现的代码。由于也是最近开始学习asp.net
mvc,如果叙述和理解有问题欢迎批评指正。 |