上篇文章中讲了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>
到此,实例完成,可以体会下这种方式与平常的开发有何异同,对模板引擎有兴趣的可参考下。