asp.net c# 利用原生aspx页面做模板引擎

其实这个是根据公司需求,才这样做的。

公司需求是这样的:

一个门户网站下面有很多个城市,比如上海、北京、天津等等,然后每个城市都可以为其指定不同的模板,而且每个模板不仅调用的数据不一样,样式也不一样。这下可把我弄晕了。咋办???自己写个模板引擎??带标签解析的??太浪费时间了吧!从网上下载一个NVelocity模板引擎?好像又不符合需求。我崩溃了。

庆幸的是我不经意间看到了这个方法:context.Server.Execute(string path),它的意思就是执行指定虚拟路径的处理程序。然后在网上又看了下别人的用法,之后我有了个大胆的想法:就用它来做模板引擎。

然后我又看到别人说这种方法效率很低。其实我倒觉得无所谓,<%@ OutputCache Duration="600" VaryByParam="*" %>这个页面缓存弄上去不就行了吗??我又做了测试,果然不加缓存,页面执行很慢,也就是一秒的样子,但是加了缓存,就是瞬间。然后我就做了个小的测试项目。

具体是这样的:

第一步,访问:Handler1.ashx?CityID=1这个页面,CityID是可变的。这个页面就会根据CityID自动判断执行哪一个aspx页面。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Web.Service
{
    /// 
    /// Handler1 的摘要说明
    /// 
    public class Handler1 : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            int CityID = Convert.ToInt32(context.Request["CityID"]);
            string TemplatePath = this.GetTemplatePathByCityID(CityID);

            //第一种
            context.Server.Execute(TemplatePath + "?" + context.Request.ServerVariables["Query_String"]);
            //第二种,下面这段生成静态文件的时候有用,如果不生成静态文件就用上面这种
            //System.IO.TextWriter tw = new System.IO.StringWriter();
            //context.Server.Execute(TemplatePath + "?" + context.Request.ServerVariables["Query_String"], tw);
            //context.Response.Write(tw.ToString());
        }

        /// 
        /// 根据CityID获取对应的aspx模板
        /// 
        /// 
        /// 
        private string GetTemplatePathByCityID(int CityID)
        {
            string TemplatePath = string.Empty; ;
            switch (CityID)
            {
                case 1:
                    TemplatePath = "~/Index1.aspx";
                    break;
                case 2:
                    TemplatePath = "~/Index2.aspx";
                    break;
                default:
                    TemplatePath = "~/Index1.aspx";
                    break;
            }
            return TemplatePath;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
} System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Web.Service
{
    /// 
    /// Handler1 的摘要说明
    /// 
    public class Handler1 : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            int CityID = Convert.ToInt32(context.Request["CityID"]);
            string TemplatePath = this.GetTemplatePathByCityID(CityID);

            //第一种
            context.Server.Execute(TemplatePath + "?" + context.Request.ServerVariables["Query_String"]);
            //第二种,下面这段生成静态文件的时候有用,如果不生成静态文件就用上面这种
            //System.IO.TextWriter tw = new System.IO.StringWriter();
            //context.Server.Execute(TemplatePath + "?" + context.Request.ServerVariables["Query_String"], tw);
            //context.Response.Write(tw.ToString());
        }

        /// 
        /// 根据CityID获取对应的aspx模板
        /// 
        /// 
        /// 
        private string GetTemplatePathByCityID(int CityID)
        {
            string TemplatePath = string.Empty; ;
            switch (CityID)
            {
                case 1:
                    TemplatePath = "~/Index1.aspx";
                    break;
                case 2:
                    TemplatePath = "~/Index2.aspx";
                    break;
                default:
                    TemplatePath = "~/Index1.aspx";
                    break;
            }
            return TemplatePath;
        }

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

 

 

之所以用一般处理程序来运行页面,是因为它不需要继承Page类,性能会好一点,而且它没有HTML元素输出。

 

第二步, Index1.aspx 或者 Index2.aspx ,这两个页面就一个单独的aspx页面了,CS文件没了。它的Inherits属性和 CodeBehind属性都被我删了。

 

 

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ OutputCache Duration="600" VaryByParam="*" %>


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>title>
head>
<body>
    <%=Request["CityID"]%>
    <form id="form1" runat="server">
    <div>
        <table border="1">
            <tr>
                <th>用户名th>
                <th>密码th>
            tr>
            <%foreach(System.Data.DataRow dr in App.Bll.Index.Instance().GetTable1().Rows){ %>
            <tr>
                <td><%=dr["username"] %>td><td><%=dr["password"] %>td>
            tr>
            <%} %>
        table>
    div>
    form>
body>
html>%@ Page Language="C#" AutoEventWireup="true" %>
<%@ OutputCache Duration="600" VaryByParam="*" %>


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>title>
head>
<body>
    <%=Request["CityID"]%>
    <form id="form1" runat="server">
    <div>
        <table border="1">
            <tr>
                <th>用户名th>
                <th>密码th>
            tr>
            <%foreach(System.Data.DataRow dr in App.Bll.Index.Instance().GetTable1().Rows){ %>
            <tr>
                <td><%=dr["username"] %>td><td><%=dr["password"] %>td>
            tr>
            <%} %>
        table>
    div>
    form>
body>
html>

 

 

第三步,就是我建了一个名称为App的项目文件,在这里面做了一个简单的数据查找。App.Bll.Index.cs

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data;

namespace App.Bll
{
    public class Index : BasePage
    {
        private static Index _index { get; set; }

        /// 
        /// 获取自己的实例
        /// 
        /// 
        public static Index Instance()
        {
            if (_index == null)
            {
                _index = new Index();
            }
            return _index;
        }

        /// 
        /// 获取数据
        /// 
        /// 
        public DataTable GetTable1()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("username");
            dt.Columns.Add("password");

            DataRow dr = dt.NewRow();
            dr["username"] = "subendong";
            dr["password"] = "123456";
            dt.Rows.Add(dr);
            dr = dt.NewRow();
            dr["username"] = "liran";
            dr["password"] = "888888";
            dt.Rows.Add(dr);
            return dt;
        }

        /// 
        /// 获取数据
        /// 
        /// 
        public DataTable GetTable2()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("title");
            dt.Columns.Add("content");

            DataRow dr = dt.NewRow();
            dr["title"] = "title1";
            dr["content"] = "content1";
            dt.Rows.Add(dr);
            dr = dt.NewRow();
            dr["title"] = "title2";
            dr["content"] = "content2";
            dt.Rows.Add(dr);
            return dt;
        }
    }
} System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data;

namespace App.Bll
{
    public class Index : BasePage
    {
        private static Index _index { get; set; }

        /// 
        /// 获取自己的实例
        /// 
        /// 
        public static Index Instance()
        {
            if (_index == null)
            {
                _index = new Index();
            }
            return _index;
        }

        /// 
        /// 获取数据
        /// 
        /// 
        public DataTable GetTable1()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("username");
            dt.Columns.Add("password");

            DataRow dr = dt.NewRow();
            dr["username"] = "subendong";
            dr["password"] = "123456";
            dt.Rows.Add(dr);
            dr = dt.NewRow();
            dr["username"] = "liran";
            dr["password"] = "888888";
            dt.Rows.Add(dr);
            return dt;
        }

        /// 
        /// 获取数据
        /// 
        /// 
        public DataTable GetTable2()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("title");
            dt.Columns.Add("content");

            DataRow dr = dt.NewRow();
            dr["title"] = "title1";
            dr["content"] = "content1";
            dt.Rows.Add(dr);
            dr = dt.NewRow();
            dr["title"] = "title2";
            dr["content"] = "content2";
            dt.Rows.Add(dr);
            return dt;
        }
    }
}

 

这样我在Aspx页面就可以调用App.Bll.Index.Instance().GetTable1()获取数据了。然后遍历循环。

 

 

 

这样整个模板引擎的雏形就出来了。

我的建议是:

1、最好把Handler1.ashx这个文件放在一个单独的web项目下面,因为它是负责处理模板调用的,就像MVC里面的Conrol一样,一般情况下它改动的时候少。

2、把aspx模板页单独做个web项目或放入一个文件夹,这样我每次发布的时候就没必要把dll文件也更新了。

 

我之所以写出来,并不是想炫耀什么,我只是想了解这样做的坏处是什么?有什么不好?希望前辈们给我说说。。谢谢!

你可能感兴趣的:(.net)