首页 > 代码库 > 不拖控件ASP.NET——NVelocity(1)

不拖控件ASP.NET——NVelocity(1)

    模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。今天我们主要来介绍NVelocity模板引擎

  1. NVelocity基础

    ?  定义

    NVelocity是一个基于.NET的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(template language)来引用由.NET代码定义的对象。从而使得界面设计人员与.NET程序开发人员基本分离。

    ?  基本语法

      1. 关键字前都加#号(例如:#if…#end以及#foreach()…#end等)

      2. 变量前都加$比如$P表示引用变量p; “$”:表示用于获得什么。(以$开头的表示“引用”意思是取得一些东东.可引用变量,属性,方法) (与JQuery相同,如果同时用时不要使用简易符号$来代替jQuery。通过jQuery.noConflict等其他方法来解决命名的冲突)。

      3.引用外部文件,有两种方式引用外部文件,#include和#parse,Include:对外部文件的引用,开始位置为模板路径;Parse:对外部文件的引用,并用nVelocity方式解析。Include与parse都有引入外部文件的作用,不同的是parse会根据nVelocity模板语言解析外部文件。也就是说如果引入当前模板,则会出现死循环。

其他的语法,详见http://blog.csdn.net/educast/article/details/6285180

    ?  运行逻辑

      NVelocity通过映射代码将数据(可以自定义,也可从数据库中取,下篇文章将讲述与数据库的交互,本节主要讲述的是自定义数据的填充)交给模板(通常是html页)进行数据填充,渲染成标准的html页,然后返回纯html页字符串,交给HttpHandler,由它返回给客户端浏览器进行解析(所有逻辑判断由HttpHandler即一般处理程序来完成)。

  2. NVelocity应用

    ?  引用方式

    使用NVelocity首先下载它的DLL,下载链接:http://download.csdn.net/detail/dragonsq1009/3666832

之后将其添加到建立的相应项目下,直接拖进项目下面即可,之后添加对它的引用即可。

    ?  例子实战

    新建一个项目,最好不要起名为NVelocity,因为如果和程序集的名字也就是你的引用集名字一样的话,当你在一个项目下在建立一个一般处理程序或者模板页(html页)会出现程序集的冲突,所以最好不要和程序集的名字一样。

    第一个简单的例子

     第一步:新建一般处理程序

<strong><span style="font-family:Microsoft YaHei;font-size:14px;">using NVelocity.App;
using NVelocity.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace NVelocity
{
    /// <summary>
    /// login 的摘要说明
    /// </summary>
    public class login : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/html";</span></strong>
<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><span style="white-space:pre">	</span>//实例化一个类,声明一个对象<span style="white-space:pre">							</span>
            person person = new person();
            person.Name = "lxn";
            person.Age = 25;

            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("p", person);//设置参数,在模板中可以通过$data来引用,将后面的值赋给前面的变量
           

            Template vltTemplate = vltEngine.GetTemplate("test.html");//设定的模板
            System.IO.StringWriter vltWriter = new System.IO.StringWriter();
            vltTemplate.Merge(vltContext, vltWriter);
            string html = vltWriter.GetStringBuilder().ToString();//经过替换后的html内容
            context.Response.Write(html);//直接输出即可

        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}</span></strong>

   第二步:新建模板页面html

<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><!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>
    $p.Name
</body>
</html>
</span></strong>

    第三步:新建person类

<strong><span style="font-family:Microsoft YaHei;font-size:14px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace NVelocity
{
    public class person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
}</span></strong>

    之后我们在浏览器中进行相应的请求,即请求一般处理程序页面,如果没有没有在iis上设置默认文档或启动文档,那么就会没有目录浏览,这样的话需要直接输入一般处理程序的名称。

    在上面的例子,我们建立一个person类,并且在一般处理程序中对其进行了赋值,之后交给了模板(html)进行数据填充,渲染成html页,之后生成的纯html文本返回给一般处理程序将,一般处理程序将其返回给浏览器进行解析,并且显示。

    第二个例子:如何对数组或者集合中元素进行遍历显示以及外部文件的引用

     一般处理程序

<strong><span style="font-family:Microsoft YaHei;font-size:14px;">using NVelocity;
using NVelocity.App;
using NVelocity.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace 引擎
{
    /// <summary>
    /// login2 的摘要说明
    /// </summary>
    public class login2 : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/html";
          <span style="margin: 0px; padding: 0px; border: none; line-height: 18px;"> //定义数据字典</span><span style="margin: 0px; padding: 0px; border: none; line-height: 18px;"> </span>
            Dictionary<string, string> dict = new Dictionary<string, string>();

            dict["tom"] = "斯坦福";
            dict["liom"] = "加利福";
            dict["lxn"] = "哈弗";
           
<span style="white-space:pre">	</span>    //映射代码
            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();//引擎初始化
<span style="white-space:pre">	</span>    //定义字符串数据
             string[] strs=new string[]{"张三","李四","王五"};</span></strong>
<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><span style="white-space:pre">	</span>    //定义泛型集合对象数据
            List<person> persons = new List<person>();
            persons.Add(new person { Name = "李晓娜", Age = 20 });
            persons.Add(new person { Name = "李晓娜", Age = 20 });
            persons.Add(new person { Name = "李晓娜", Age = 20 });
            

            VelocityContext vltContext = new VelocityContext();//创建上下文,是为了传输数据使用的
            vltContext.Put("ps", dict);//设置参数,在模板中可以通过$data来引用,前面的data值即为value值

            vltContext.Put("minren", strs); //填充数据,交给下面的模板(test2.html)
            vltContext.Put("per", persons);
            vltContext.Put("age", 30);

            Template vltTemplate = vltEngine.GetTemplate("test2.html");
            System.IO.StringWriter vltWriter = new System.IO.StringWriter();
            vltTemplate.Merge(vltContext, vltWriter);
            string html = vltWriter.GetStringBuilder().ToString();//经过替换后的html内容
            context.Response.Write(html);//直接输出即可
           }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}</span></strong>

   模板html页分为三部分

     Head的html页

<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><!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>
<p>欢迎光临!$age</p>
</span></strong>

     Foot的html页

<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><p>本网站版权所有!$age</p>
</body>
</html>
</span></strong>

      内容区域的html页

<strong><span style="font-family:Microsoft YaHei;font-size:14px;">
#parse("head.html")

 
    <!--1.显示定义的字符串数据-->
    <ul>
        #foreach($mr in $minren )
        <li>$mr</li>
        #end
    </ul>
    <!--2.通过数组对其进行遍历,并且嵌套条件查询-->
    <ul>
        #foreach($p in $per)
            #if($p.Age>20)
                <li style="color:red">$p.Name的年龄是$p.Age</li>
                <li><input type="text" value=http://www.mamicode.com/"$p.Name" />>
    效果图:

技术分享

    在这里我们通过:

      1、#foreach($element in $list)……this is $element……#end把数组显示输出到界面上。

      2、通过条件语句#if(condtion)……#elseif(condtion)……else……#end根据条件判断应该显示的信息,不仅可以单独显示,同样可以嵌入到遍历语句当中。

      3、通过两种方式引用外部文件,include不会根据NVelocity模板语言解析外部文件,而parse会根据nVelocity模板语言解析外部文件。注意当使用include或者parse时最好不好将另一个注释,这样在解析的时候会将其下面的代码当做注释不予显示,所以最好写一个即可,另一个直接替换掉。

    如下面这样写是出问题的,自己试试。
<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><!--#include("head.html")-->
#parse("head.html")
</span></strong>

    第三个例子:NVelocity封装

      1、如果某班上需要数据很多(比如填写个人信息),那么就需要传递很多参数,这样很麻烦,可以把这些参数封装到一个类中,这样$data.Name,$data.Age就可以了。不过写不同的页面都要写一个这样的类太麻烦,C#3.0中提供了“匿名类”,varperson=new{Name=”lixiaona”,Age=25};相当于声明一个有Name、Age两个属性的类,new这个类的一个实例,并且用变量声明为“自动推断”的变量var,后面就可以这样用了int i=person.Name.属性是只读的。

      2、 将datatable传递给Nvelocity的时候需要传递datatable.Rows.

      3、 为了减少解析模板的时间,我们可以根据需要启用Nvelocity缓存。

   封装实例:

     一般处理程序页面:

<strong><span style="font-family:Microsoft YaHei;font-size:14px;">using NVelocity;
using NVelocity.App;
using NVelocity.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace 引擎
{
    /// <summary>
    /// displayNew 的摘要说明
    /// </summary>
    public class displayNew : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/html";
            
            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();//引擎初始化

            var news = new { Title = "特大喜讯", Author = "lxn", PostDate = "2015-1-8", msg = "成功晋级" };
            VelocityContext vltContext = new VelocityContext();//创建上下文,是为了传输数据使用的
            vltContext.Put("data", news);//设置参数,在模板中可以通过$data来引用,前面的data值即为value值


            Template vltTemplate = vltEngine.GetTemplate("displayNew.html");
            System.IO.StringWriter vltWriter = new System.IO.StringWriter();
            vltTemplate.Merge(vltContext, vltWriter);
            string html = vltWriter.GetStringBuilder().ToString();//经过替换后的html内容
            context.Response.Write(html);//直接输出即可
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}</span></strong>

       Html页面:

<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>$data.Title</title>
</head>
<body>
    <h1>$data.Title</h1>
    <p>作者:$data.Author;发布日期:$data.PostDate</p>
    <p>$data.msg</p>
</body>
</html>
</span></strong>

      效果图:

技术分享

    ?  Nvelocity代码

      由前面的三个例子我们来看看Nvelocity的映射代码:首先我们需要引入命名空间:主要是三个分别为:using NVelocity;using NVelocity.App;usingNVelocity.Runtime;

<strong><span style="font-family:Microsoft YaHei;font-size:14px;">//用的时候考代码即可,只需改三个地方:模板所在文件夹、添加数据、设定模板  
VelocityEngine vltEngine = new VelocityEngine();  
vltEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file");  
vltEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, System.Web.Hosting.HostingEnvironment.MapPath("~/templates"));//模板文件所在的文件夹,例如我的模板为templates文件夹下的TestNV.html  
vltEngine.Init();  
  
VelocityContext vltContext = new VelocityContext();  
vltContext.Put("dataName", person);//添加数据,在模板中可以通过$dataName来引用数据   
vltContext.Put("dataName2", person);//可添加多个数据,基本支持所有数据类型,包括字典、数据、datatable等  
Template vltTemplate = vltEngine.GetTemplate("TestNV.html");//设定模板  
System.IO.StringWriter vltWriter = new System.IO.StringWriter();  
vltTemplate.Merge(vltContext, vltWriter);  
  
string html = vltWriter.GetStringBuilder().ToString();  
context.Response.Write(html);//返回渲染生成的标准html代码字符串  </span></strong>

 3.      总结

    通过以上的几个例子,我们对于Nvelocity的开发过程有了一个初步的理解,那就是前面我们说过的运行逻辑,如果稍微注意点我们发现这里写的例子都是在页面中直接属性的没有和数据库打交道,只是一些简单的应用,接下来我们会讲解与数据库交互的操作,请继续关注~




不拖控件ASP.NET——NVelocity(1)