惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
云风的 BLOG
云风的 BLOG
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Announcements
Recent Announcements
IT之家
IT之家
Google DeepMind News
Google DeepMind News
罗磊的独立博客
爱范儿
爱范儿
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
U
Unit 42
MongoDB | Blog
MongoDB | Blog
S
SegmentFault 最新的问题
B
Blog
博客园 - 叶小钗
月光博客
月光博客
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
C
Check Point Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

博客园 - Kingthy

【开源项目】智能电视及电视盒子的控制应用TVRemoteIME的接口说明 实现安卓里边下边播的播放器(源码公开) 现在很火的答题赢钱游戏,让我来简单教你怎么做自动答题器 【开源项目】电视盒子好用又强大的APP: TVRemoteIME [原创]用C#实现微信“跳一跳”小游戏的自动跳跃助手 javascript图片隐写术,感觉可以用它来干点有想法的事情 我的KT库之----数据库的操作(DbCommandBuilder/DbConditionBuilder) VTemplate模板引擎的使用—Function标签 我的KT库之----数据库的操作(DbCommandExecutor) 我的KT库之----数据库的操作(DbHelper) 我的KT库之----数据对象 【原创】腾讯微博的XSS攻击漏洞 我的KT库之-----缓存与配置 我的KT库之-----对象池 我的KT库之-----扩展方法 我的KT库之-----认识KT [开源]基于C#的腾讯微博SDK V0.1版本发布 怪异的StackOverflowException异常 开源的Kingthy.Mail邮件组件库
我的KT库之----与VT的结合
Kingthy · 2011-09-14 · via 博客园 - Kingthy

了解或者认识KT:

http://www.cnblogs.com/kingthy/archive/2011/08/08/2130973.html

在项目中如何使用KT?

KT是一个库,所以将KT的dll文件引用到您的项目上即可使用KT里的函数功能。

本节将介绍大家如何将KT与VT结合进行Web项目的开发。KT里的与VT相关的操作对象存放于在“KT.Framework.Web“下,当你已在你的项目里引用了KT库后,写下以下代码就可以使用了。

using KT.Framework.Web;

什么是VT?

VT是VTemplate模板引擎的简称,你可以从下面链接里了解此模板引擎的相关资料

http://www.cnblogs.com/kingthy/archive/2009/08/17/net-vtemplate.html

KT里的VTemplatePage对象

在Web Form页面开发,我们很多页面都是基于System.Web.UI.Page这个对象,这是因为Page对象帮我们实现了IHttpHandler接口,以便我们的“.aspx”页面能处理一个HTTP会话,并且对HTTP会话进行了“事件包装”,使我们能在开发中使用到Web Form里的各种事件驱动。如果我们在项目页面中直接使用VT进行处理数据,那么我们可以抛弃掉Page这个“笨重”的东西,因为我们不再需要那些WEB控件,也不再需要Page中那过于“复杂”的事件模型。我们只需要一个简单的“事件模型”即可,如下:

e

(当然,实际上是不可能就这么简单的微笑)

VTemplatePage对象则是对上面流程的实现,它也是基于IHttpHandler接口的实现。

VTemplatePage对象的事件流程

上面中的各个事件方法,在VTemplatePage里都是以虚方法实现的,因此在开发时,我们可以根据需要重载上面里的任一个事件方法,以便在某个阶段做额外的处理,比如:在“OnInit“事件里我们做用户权限判断处理,如果当前用户没有访问权限我们就可以拒绝他继续访问页面。

VTemplatePage对象特别的对以下几个事件方法进行了实现处理,以便我们开发时能够更快速开发。

1、OnProcessAjaxHandler : Ajax委托处理事件函数,用于处理Ajax方法。(在下面会详细对此介绍)

2、OnLoad : 页面装载事件函数,此方法衍生一个抽象方法: InitPageTemplate, 使我们在开发时只关注此抽象方法的实现即可。并且此事件方法还增加了一个简单的缓存处理。(关于缓存见下面的LoadPageCache与SavePageCache方法解释)

3、OnRender : 呈现页面数据事件函数,用于呈现模板数据并Response回客户端。此事件方法增加了简单缓存的处理功能。(关于缓存见下面的LoadPageCache与SavePageCache方法解释)

在了解VTemplatePage对象前,让我们先了解另外一个对象。

站点配置对象WebSiteConfiguration

此配置对象用于设置站点项目的参数,比如设置站点项目路径信息、页面模板的参数信息、站点上传文件设置参数等数据。

此对象可以映射为某个XML配置文件进行管理。如下面的XML示例:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <!--设置站点的域名,如: "http://www.host.com/"。如果为空则默认-->
  <HostName></HostName>
  <!--设置站点所在的根目录,默认为: "/"-->
  <RootPath>/</RootPath>
  <!--设置站点的绝对路径地址,如: "c:\wwwroot\web\", 如果为空则默认-->
  <AppPath></AppPath>
  <!--设置站点模板文件存放的目录,默认为: "template/default/"-->
  <TemplatePath>template/default/</TemplatePath>
  <!--设置站点模板文件的扩展名,如: ".html"-->
  <TemplateFileExt><![CDATA[.html]]></TemplateFileExt>
  <!--设置站点模板文件的编码,如: "gb2312"-->
  <TemplateFileCharset>utf-8</TemplateFileCharset>

</configuration>

如需更详细的可以查看KT项目doc目录下的website.default.config配置文件。

在使用时,直接调用From<T>方法获取配置对象。如下:

WebSiteConfiguration config = WebSiteConfiguration.From<WebSiteConfiguration>("website.config");

在实际项目开发时,可以根据需要对此对象进行扩展,以增加其它站点参数。

VTemplatePage的使用

A、VTemplatePage对象的属性

1、Context : 返回当前的System.Web.HttpContext对象

2、Request : 返回当前的System.Web.HttpRequest对象

3、Response : 返回当前的System.Web.HttpResponse对象

4、Server : 返回当前的System.Web.HttpServerUtility对象

5、Session : 返回当前的System.Web.HttpSessionState对象

6、Application : 返回当前的System.Web.HttpApplicationState对象

7、Document  : 返回或设置当前的TemplateDocument对象

8、DocumentConfig : 返回当前的TemplateDocumentConfig对象,用于设置模板文档的相关解析配置。这是一个虚属性,开发中可根据需要重写此属性。

9、DocumentIsLoaded : 返回判断Document是否已装载,即模板文档是否已装载

10、IsPostBack : 返回当前页面是否是以POST方式访问

11、Configuration :返回当前页面站点的WebSiteConfiguration对象,也就是站点的配置参数。此属性是一个抽象属性。

12、PageCacheExpireTime : 返回当前页面的缓存过期时效(单位:秒钟,默认为1小时,如果小于等于0则不缓存),此属性是一个虚属性,需要页面需要缓存功能,必须重写此属性

13、PageCacheFileName : 返回当前页面的缓存文件绝对地址,此属性是一个虚属性,如果需要使用页面缓存则必须重写此属性并返回真实地址

B、VTemplatePage对象的方法

1、LoadTemplateFromFile : 从模板文件里装载模板,调用此方法后,将会对Document属性进行实例化。

2、LoadCurrentPageTemplate : 装载当前访问页面对应的模板。

    当前访问页面对应的模板文件地址由Configuration里的配置参数计算得出,比如Configuration的配置参数为上面的XML示例里的配置。如果当前的访问页面地址为

/user/profile.ashx

    那么此页面对应的模板文件即为

/template/default/user/profile.html
而如果Configuration里配置RootPath为“/apps/”,那么如果访问地址为
/apps/user/profile.ashx

那么此页面对应的模板文件即为

/apps/template/default/user/profile.html

3、LoadPageCache : 装载此页面的缓存。如果页面已重写了PageCacheExpireTimePageCacheFileName两个属性,则此方法会判断PageCacheFileName文件是否存在,如果存在并且距上次更改时间还没有超出PageCacheExpireTime的设置时间间隔,则将会直接输出(Response)缓存文件里的数据。

4、SavePageCache : 保存当前的页面到缓存里。如果页面已重写了PageCacheExpireTimePageCacheFileName两个属性,则此方法判断当前是否已装载了模板,如果是,则将模板数据解析到缓存文件里存储。

5、InitPageTemplate : 初始化当前的页面模板。此方法是一个抽象方法,在OnLoad事件发生时被调用。此方法类似于Web Form里的Page_Load方法。

C、VTemplate对象的简单开发示例

通过上面了解了VTemplatePage的属性与方法后,现在我们可以使用它来做页面开发了。下面跟我一步一步来做一个简单的开发示例

1、打开你的Visual Studio, 新建一个Web项目(Web Application或者Web Site项目都可以),将KT库引入到您的项目里

2、在项目里新建一个“一般处理程序”页面,也就是“.ashx”页面。比如叫“firstpage.ashx”,确定后VS会帮我们生成一个".ashx”与".ashx.cs”文件。其中".ashx.cs”文件里面的内容如下:

/// <summary>
/// firstpage 的摘要说明
/// </summary>
public class firstpage : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Write("Hello World");
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

注:对于使用“一般处理程序.ashx”页面,是因为上面所说的,我们不需要Page里的太过于“复杂”的事件模型,我们只需要简单的事件模型即可。经常有群友在群里说“aspx比ashx好”、“为什么你用ashx,不用aspx呢?”、“VT能在aspx下用吗?”等等问题,当你看到我这里的讲解时,我相信你的心里已有答案了吧?aspx与ashx没有谁比谁好,aspx可以说是为webform而生的,因为aspx里的事件模型就是为webform而做的。

3、改写一下页面的.cs代码文件里的代码,比如将上面的代码改为如下

/// <summary>
/// firstpage 的摘要说明
/// </summary>
public class firstpage : VTemplatePage
{
    /// <summary>
    /// 初始化页面模板
    /// </summary>
    public override void InitPageTemplate()
    {
        this.LoadCurrentPageTemplate();
    }

    /// <summary>
    /// 站点的配置
    /// </summary>
    public override WebSiteConfiguration Configuration
    {
        get 
        {
            return WebSiteConfiguration.From<WebSiteConfiguration>("website.config");
        }
    }
}

我们的页面继承于VTemplatePage对象,由于VTemplatePage对象是一个抽象对象,所以我们还需要实现其的一个抽象方法与一个抽象属性。其中在InitPageTemplate方法里我们调用LoadCurrentPageTemplate方法,装载当前页面对应的模板文件,在Configuration属性里返回当前项目站点的配置。

4、在站点目录下建立配置文件存放目录"config",在上面代码里,我们的站点配置是从"website.config”这个配置文件读取的,所以我们需要在配置文件目录建一个website.config文件并且配置好(我们可以直接拷贝VT项目里的"website.default.config”示例文件)

5、在站点目录下建模板目录"template/default/”(此目录路径由配置文件来决定),并在此目录一个模板文件"firstpage.html”(模板文件的扩展名也是由配置文件决定)。示例模板:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> KT与VT的结合 --  第一个页面 </title>
<link type="text/css" rel="stylesheet" href="{$Page.TemplatePath}css/common.css" />
</head>
<body>
<h4>KT与VT的结合 --  第一个页面</h4>
<ol>
<li>Page = <span>{$Page}</span></li>
<li>Page.SitePath = <span>{$Page.SitePath}</span></li>
<li>Page.SiteUrl = <span>{$Page.SiteUrl}</span></li>
<li>Page.TemplatePath  = <span>{$Page.TemplatePath}</span></li>
<li>Page.Request.Url  = <span>{$Page.Request.Url}</span></li>
<li>当前服务器时间 = <span><vt:serverdata type="time" output="true" /></span></li>
</ol>
</body>
</html>

注:在调用LoadCurrentPageTemplate方法后,VTemplatePage对象会自动将以下4个变量赋值到模板文件里,也就是我们可以在模板文件里随时调用此4个变量对象。

A、Page变量 : 当前的页面对象,如上面的"firstpage”对象

B、Page.SitePath变量: 当前的站点的根目录地址,此变量值由配置文件的RootPath参数决定。如“/”

C、Page.SiteUrl变量: 当前的站点URL地址。如“http://www.hostname.com/”

D、Page.TemplatePath 变量: 相对于当前站点根目录地址的模板路径地址,此变量值由配置文件的TemplatePath参数决定。如"/template/default/”

经过上面几步后,我们的项目可以编译运行了,结果如下面的运行示例截图

image

我们的模板与页面成功进行了“绑定”,后面要如何去做就是发挥你们的才智时间了微笑

D、VTemplatePage对象里的简单缓存功能的启用

VTemplatePage对象的缓存功能是默认是简单采用对比缓存文件的更改时间来维护缓存的变化(如果需要更复杂的缓存处理,则可以重写LoadPageCacheSavePageCache方法),如果需要在页面上启用简单缓存功能,则重写PageCacheExpireTimePageCacheFileName两个属性即可,如下面对firstpage.ashx页面的修改

/// <summary>
/// firstpage 的摘要说明
/// </summary>
public class firstpage : VTemplatePage
{
    /// <summary>
    /// 初始化页面模板
    /// </summary>
    public override void InitPageTemplate()
    {
        this.LoadCurrentPageTemplate();
    }

    /// <summary>
    /// 站点的配置
    /// </summary>
    public override WebSiteConfiguration Configuration
    {
        get 
        {
            return WebSiteConfiguration.From<WebSiteConfiguration>("website.config");
        }
    }

    /// <summary>
    /// 缓存1分钟后过期
    /// </summary>
    protected override int PageCacheExpireTime
    {
        get
        {
            return 60;
        }
    }
    /// <summary>
    /// 缓存文件
    /// </summary>
    protected override string PageCacheFileName
    {
        get
        {
            return this.Configuration.ToAbsoluteAppPath("cache/firstpage.html");
        }
    }
}

经过上面修改后,我们的"firstpage.ashx”页面在1分钟之内,不管刷新多少次,页面上显示的“服务器时间”都是不变,直到60秒后缓存失效。并且会在站点根目录下的cache目录生成一个firstpage.html缓存文件(注:对于POST方式访问页面则默认不会启用缓存功能)

E、VTemplatePage对象的Ajax方法委托处理

先让我们认识一下“AjaxHandlerMethodAttribute”特性类,此特性用于标记某个方法是否为Ajax方法委托方法。

共有以下几个属性定义:

1、Name : 定义用于处理的Ajax方法,如果未定义(null)则表示与实际的函数方法名称一样。此名称将与用户提交的"ajaxhandler"参数(QueryString或者Form)匹配

2、Description : 用于定义描述此Ajax方法的说明

3、ContentType : 用于定义输出数据的内容类型,如text/xml; text/plain; text/html; application/x-javascript等等。如果未定义则会自动根据ReturnType返回

4、AllowBrowserCache : 是否允许浏览器缓存方法的处理结果,默认不允许

5、IsTerminative : 是否在处理AJax方法委托后自动中止页面执行

6、ReturnType : 数据的访问类型,如JSON、Text等,默认是Auto(自动根据方法返回值处理:如果方法返回非null值则按Json数据处理,否则按空返回处理)

我们修改一下上面的"firstpage.ashx”页面的代码,增加两个Ajax委托方法:

/// <summary>
/// firstpage 的摘要说明
/// </summary>
public class firstpage : VTemplatePage
{
    /// <summary>
    /// 初始化页面模板
    /// </summary>
    public override void InitPageTemplate()
    {
        this.LoadCurrentPageTemplate();
    }

    /// <summary>
    /// 站点的配置
    /// </summary>
    public override WebSiteConfiguration Configuration
    {
        get 
        {
            return WebSiteConfiguration.From<WebSiteConfiguration>("website.config");
        }
    }


    /// <summary>
    /// 获取时间值
    /// </summary>
    /// <returns></returns>
    [AjaxHandlerMethod("timer")]
    public long GetTimer()
    {
        return DateTime.Now.Ticks;
    }

    /// <summary>
    /// 获取数据
    /// </summary>
    /// <returns></returns>
    [AjaxHandlerMethod("data")]
    public object GetData()
    {
        string r = Request.Form["r"];
        return new
        {
            id = DateTime.Now.Ticks,
            rnd = r
        };
    }
}

为了能达到演示效果,我们也将"firstpage.ashx”页面对应的"firstpage.html”模板文件做一下相应的修改,增加Ajax的脚本调用,如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> KT与VT的结合 --  第一个页面 </title>
<link type="text/css" rel="stylesheet" href="{$Page.TemplatePath}css/common.css" />
</head>
<body>
<h4>KT与VT的结合 --  第一个页面</h4>
<ol>
<li>Page = <span>{$Page}</span></li>
<li>Page.SitePath = <span>{$Page.SitePath}</span></li>
<li>Page.SiteUrl = <span>{$Page.SiteUrl}</span></li>
<li>Page.TemplatePath  = <span>{$Page.TemplatePath}</span></li>
<li>Page.Request.Url  = <span>{$Page.Request.Url}</span></li>
<li>当前服务器时间 = <span><vt:serverdata type="time" output="true" /></span></li>
</ol>
<h4>Ajax操作区</h4>
<input type="button" value="获取Timer值" id="b1" /><input type="button" value="获取数据" id="b2" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
    $('#b1').click(function () {
        $.post('?', { ajaxhandler: 'timer' }, function (timer) {
            alert('timer=' + timer);
        }, 'json');
    });
    $('#b2').click(function () {
        $.post('?', { ajaxhandler: 'data', r : Math.random() }, function (d) {
            alert('data=' + d);
        }, 'text');
    });
</script>
</body>
</html>

最终编译后运行,页面效果如下

image

当我们点击上面两个按钮,将可分别获取对应的数据。

VTemplatePage对象处理Ajax方法委托的简单原理:在HTTP会话开始时,查看QueryString或Form参数里是否有ajaxhandler值,如果有则判断当前页面对象是否包有AjaxHandlerMethodAttribute特性且名称定义相同的公开方法,如果有则调用方法。

注意:根据我们最上面的VTemplatePage事件流程图可知,我们的Ajax方法优先于OnLoad(InitPageTemplate)方法的执行,也就是在我们的Ajax方法被执行时,我们的页面模板是还没有装载的,所以请勿在Ajax委托方法里处理模板,如需要操作请先“装载模板”。

说明 :上面所说的示例项目代码,来源于KT.WebApp项目

http://kt.codeplex.com/SourceControl/changeset/view/9738#