一、前言
本节我们将实际实现一个简单的NVelocity解析环境,以便为以后的实例做一些基本工作,虽然NVelocity如何使用已经属于老掉牙的话题,但我只能专门挑出来一章来做铺垫.人生就是这样无奈啊.不过请您放心,不会耗去您太多的时间.
二、项目搭建
- 1.新建一个”ASP.Net 空Web应用程序”,.Net版本请选择4,项目命名为:SW.VMTest,并”为解决方案创建目录”
- 2.在解决方案下再新建一个类库项目:SW.VMTest.Library
- 3.续上文,在SW.VMTest.Library 上引用您下载到的4.0/NVelocity.dll
- 4.新建一个NVelocityEngine类:
using Commons.Collections; using NVelocity; using NVelocity.App; using System; using System.Collections; using System.IO; using System.Web; namespace SW.VMTest.Library { public class NVelocityEngine { public VelocityContext Context { get; set; } private VelocityEngine _Engine { get; set; } public NVelocityEngine(HttpContext httpContext) { ExtendedProperties ep = new ExtendedProperties(); //#foreach 计数器初始值 ep.AddProperty("directive.foreach.counter.initial.value", 0); //是否允许设置为null ep.AddProperty("directive.set.null.allowed", false); //模板路径 ep.AddProperty("file.resource.loader.path", AppDomain.CurrentDomain.BaseDirectory + "\\Template"); _Engine = new VelocityEngine(ep); //Context init Hashtable hs = new Hashtable(); hs.Add("Session", httpContext.Session); hs.Add("Request", httpContext.Request); hs.Add("Server", httpContext.Server); hs.Add("ObjHelper", new ObjectHelper()); Context = new VelocityContext(hs); } public bool Merge(string templateName, TextWriter writer) { bool result = _Engine.MergeTemplate(templateName, "UTF-8", Context, writer); if (!result) _Engine.Error("模板解析失败!"); return result; } public bool Evaluate(TextWriter writer, string inString) { bool result = _Engine.Evaluate(Context, writer, "Error", inString); if (!result) _Engine.Error("模板解析失败!"); return result; } } }
- 5.继续在在SW.VMTest.Library 项目上引用System.Web
- 6.新建一个SHtmlHandler类:
using System.IO; using System.Web; namespace SW.VMTest.Library { public class SHtmlHandler : IHttpHandler { public bool IsReusable { get { return false; } } public void ProcessRequest(HttpContext context) { NVelocityEngine _nVe = new NVelocityEngine(context); string filePath = context.Request.Path.TrimStart('\\').Replace(".shtml", ".vm"); StringWriter writer = new StringWriter(); _nVe.Merge(filePath, writer); context.Response.Clear(); context.Response.Write(writer); context.Response.End(); } } }
- 7.在SW.VMTest.Library上新建一个文件夹,命名为Helper
- 8.在Helper文件夹内新建一个ObjectHelper类:
using System; namespace SW.VMTest.Library { public class ObjectHelper { public object GetObject(string typeName) { return GetObject(typeName, null); } public object GetObject(string typeName, params object[] args) { Type type = Type.GetType(typeName); if (type == null) throw new ArgumentException("找不到具体的类型"); object obj; if (args != null) obj = Activator.CreateInstance(type, args); else obj = Activator.CreateInstance(type); return obj; } } }
- 9.在SW.VMTest项目上修改Web.config文件:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> <httpHandlers> <add path="*.shtml" verb="*" type="SW.VMTest.Library.SHtmlHandler, SW.VMTest.Library"/> </httpHandlers> </system.web> </configuration>
- 10.在SW.VMTest项目上创建新文件夹Template
- 11.Template文件夹上点右键,选择”在文件资源管理器中打开此文件”
- 12.在打开的文件夹中创建一个空白的.txt文档,并修改文件名为”test.vm”
- 13.点击vs”工具”->”选项”->”文本编辑器”->”文件扩展名”,添加如下图项目,确定
14.点击解决方案管理中的”显示文件”按钮
- 15.找到Template文件夹下的Test.vm,右击,选择”包含进项目”
- 16.打开Test.vm文件,输入以下代码:
<html> <head> <title>Test Page</title> </head> <body> <h1>Hello World</h1> <ul> #foreach($item in [1..5]) <li>I'm the list$item with index $velocityCount</li> #end </ul> <p>$Server.MapPath('aaa.aspx')</p> <p>$Request.QueryString.get_item('aa')</p> #set($dictionary = $ObjHelper.GetObject('System.Collections.Generic.Dictionary`2[[System.Int32],[System.Int32]]')) $dictionary.Add(1,123) $dictionary.Add(2,223) $dictionary.Add(3,323) <p>$dictionary.get_item(1)</p> </body> </html>
- 17.运行,输入以下地址:
http://localhost:3205/test.shtml?aa=hahaha
- 18.请确认是否为以下界面,如果不,请检查步骤.
三、说明
以下是上述步骤的一些说明:
NVelocityEngine类
任何一个习惯语言的人,我想都最好还是不要打破他们索引从0起的习惯吧.所以directive.foreach.counter.initial.value=0是有必要在配置里面的
而在一个网站系统里面,把所有的模板都放在一个目录,我认为就方便查找的原因来讲,也是需要重视的.本节配置里面file.resource.loader.path我设置为根目录下的Template文件夹
为了后文能有更多的例子可以讲,我特意在Context里面加入了Session、Request、Server和一个简易的ObjectHelper
SHtmlHandler类
本类的主要目的就是将.shtml的请求交给本类来处理.
ObjectHelper
我们知道在NVelocity里面是不能new出对象的.ObjectHelper的目的便在于此,通过反射来得到新的对象.
其他
将vm设置为HTML编辑器打开可以解决HTML标签的着色问题,当然这个问题在后文我们会解决,但为了暂时的书写方便,先设置为HTML编辑器.毕竟全是黑字,时间长了,会很费眼睛的.
四、还有些要说的
实际上,在任何一个系统级别的应用,仅仅编写以上代码是不够的,对于缓存的处理,更丰富的帮助类,都是必须的.
但仅以上内容对于后面系列的文章就足够了.
另外我十分头疼这个代码插件,为什么不能折叠起来呢?