上篇文章中讲了NVelocity的基本原理,一些简单的数据操作,以及模板语言的部分逻辑处理。这里用一个实例简单介绍NVelocity在传统的Web开发中与数据库的交互。
就以一个“人员(包含姓名、年龄、邮箱三个字段)”的增删改查为例,如下为数据库设计:
先看一下做完后的效果,分为“人员列表”和“编辑页面”,人员列表页查询出所有的人员信息,进行显示。点击新增或编辑按钮则进入“编辑页面”,点击删除直接将信息删除。如下图:
点击“新增”:
点击“编辑”(第一条记录):
就这么一个小功能,不多说,直接看代码:
首先将NVelocity的“渲染代码”封装在一个类CommonHelper中,代码:
public class CommonHelper
{
/// <summary>
/// 用data数据填充templateName模板,渲染生成html,返回
/// </summary>
/// <param name="templateName">模板页名字</param>
/// <param name="data">所填充的数据</param>
/// <returns>渲染生成的Html字符串</returns>
public static string RenderHtml(string templateName, object data)
{
VelocityEngine vltEngine = new VelocityEngine();
vltEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file");
vltEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, System.Web.Hosting.HostingEnvironment.MapPath("~/templates"));//模板文件所在的文件夹
vltEngine.Init();
VelocityContext vltContext = new VelocityContext();
vltContext.Put("Data", data);//填充数据,在模板中可以通过$data来引用
Template vltTemplate = vltEngine.GetTemplate(templateName);//模板页名字
System.IO.StringWriter vltWriter = new System.IO.StringWriter();
vltTemplate.Merge(vltContext, vltWriter);
string html = vltWriter.GetStringBuilder().ToString();
return html;
}
}
然后,由于涉及到数据库操作,所以需要一个SqlHelper类,代码很常见,这里不显示。
然后,建立人员列表的一般处理程序PersonList.ashx,代码如下:
public class PersonList : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/html";
DataTable dt= SqlHelper.ExecuteDataTable("select * from T_Persons");
//DataTable不是集合,所有无法foreach遍历,DataTable的Row属性代表表格中数据行的集合,一般传DataTable的Rows对象给
string html = CommonHelper.RenderHtml("PersonList.html",dt.Rows);
context.Response.Write(html);
}
public bool IsReusable
{
get
{
return false;
}
}
}
然后,建立人员列表的模板页PersonList.html(放于根目录下的templates文件夹下,用于显示和删除人员信息),代码如下:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>人员列表</title>
</head>
<body>
<a href="../PersonEdit.ashx?Action=AddNew">新增</a>
<table border="1" style="border-collapse:collapse;">
<!--定义table的表头-->
<thead style="color:red">
<tr>
<td>删除</td>
<td>编辑</td>
<td>姓名</td>
<td>年龄</td>
<td>邮箱</td>
</tr>
</thead>
<!--定义table的正体-->
<tbody>
<!--循环遍历$Data中的数据并显示-->
#foreach($person in $Data)
<tr>
<td><a href="../PersonEdit.ashx?Action=Del&Id=$person.Id">删除</a></td>
<td><a href="../PersonEdit.ashx?Action=Edit&Id=$person.Id">编辑</a></td>
<td>$person.Name</td>
<td>$person.Age</td>
<td>$person.Email</td>
</tr>
#end
</tbody>
</table>
</body>
</html>
然后,建立编辑页面的一般处理程序PersonEdit.ashx(该页面进行编辑、新增的“显示和保存”逻辑处理),代码如下:
public class PersonEdit : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/html";
string action=context.Request["action"];
if (action == "AddNew")
{
//判断是否含有Save并且等于True,如果是的话说明点击了保存按钮
bool save=Convert.ToBoolean(context.Request["Save"]);
if (save)//是保存
{
string name = context.Request["Name"];
int age = Convert.ToInt32(context.Request["Age"]);
string email=context.Request["Email"];
SqlHelper.ExecuteNonQuery("insert into T_Persons(Name,Age,Email) values (@Name,@Age,@Email)",new SqlParameter("@Name",name),new SqlParameter("@Age",age),new SqlParameter("@Email",email));
context.Response.Redirect("PersonList.ashx");//保存成功返回列表页
}
else
{
//定义匿名对象
var data = new { Action = "AddNew", Person = new { Name = "", Age = 20, Email = "@rupeng.com" } };
//进行渲染
string html = CommonHelper.RenderHtml("PersonEdit.html",data);
context.Response.Write(html);
}
}
else if (action == "Edit")
{
//判断是否含有Save并且等于True,如果是的话说明点击了保存按钮
bool save = Convert.ToBoolean(context.Request["Save"]);
if (save)
{
//所有的信息服务器端尽量不要记,尽量通过客户端传递
//服务器是一个健忘症(无状态),服务器只认识Request中的信息
long id = Convert.ToInt64(context.Request["Id"]);
string name = context.Request["Name"];
int age = Convert.ToInt32(context.Request["Age"]);
string email = context.Request["Email"];
SqlHelper.ExecuteNonQuery("update T_Persons set Name=@Name,Age=@Age,Email=@Email where Id=@Id", new SqlParameter("@Id", id), new SqlParameter("@Name", name), new SqlParameter("@Age", age), new SqlParameter("@Email", email));
context.Response.Redirect("PersonList.ashx");
}
else
{
long id = Convert.ToInt64(context.Request["Id"]);
DataTable dt = SqlHelper.ExecuteDataTable("select * from T_Persons where Id=@Id", new SqlParameter("@Id", id));
if (dt.Rows.Count <= 0)
{
context.Response.Write("没有找到Id=" + id + "的数据");
}
else if (dt.Rows.Count > 1)
{
context.Response.Write("找到多条Id=" + id + "的数据");
}
else
{
DataRow dr = dt.Rows[0];
var data = new { Action = "Edit", Person = dr };
string html = CommonHelper.RenderHtml("PersonEdit.html", data);
context.Response.Write(html);
}
}
}
else if (action == "Del")
{
long id = Convert.ToInt64(context.Request["Id"]);
SqlHelper.ExecuteNonQuery("delete from T_Persons where Id=@Id", new SqlParameter("@Id",id));
context.Response.Redirect("PersonList.ashx");
}
else
{
context.Response.Write("Action参数错误!");
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
然后,建立编辑页面的模板页面PersonEdit.html(位于根目录下的templates文件夹下),代码如下:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>
#if($Data.Action=="AddNew")
新增用户
#else
编辑用户:$Data.Person.Name
#end
</title>
</head>
<body>
<form action="PersonEdit.ashx" method="post">
<input type="hidden" name="Action" value="$Data.Action" />
<input type="hidden" name="Save" value="true" />
<input type="hidden" name="Id" value="$Data.Person.Id" />
<table style="background-color:yellowgreen">
<tr><td>姓名:</td><td><input type="text" name="Name" value="$Data.Person.Name" /></td></tr>
<tr><td>年龄:</td><td><input type="text" name="Age" value="$Data.Person.Age" /></td></tr>
<tr><td>邮箱:</td><td><input type="text" name="Email" value="$Data.Person.Email"/></td></tr>
<tr><td></td><td><input type="submit" value="保存"/></td></tr>
</table>
</form>
</body>
</html>
到此,实例完成,可以体会下这种方式与平常的开发有何异同,对模板引擎有兴趣的可参考下。