小弟今年6月份刚刚毕业。前天刚刚开始接触秋色园这个开源框架,感觉收获颇多,在此写了一个测试项目,加上了一个自己写的路由机制。还望各位看官见笑了。
我的项目分为:UrlRewrite层,UrlRewriteModule层,WebUI层。
UrlRewrite层用于当http处于刚刚进来的时候用HttpModule处理路由操作。
UrlRewriteModule层里面继承了一个HttpHandler为页面基类,在里面设定了整张页面的生命周期。
WebUI层是web应用层。
如下图:
我的路由机制设定的URL格式是这样的:~/模块名/页面名(不加后缀)?参数
其中模块名如果你是在根目录下的如Default.ashx页面则为Home,其他是对应其文件夹名的如AdminDefault.ashx的模块名为Admin。
在第一次接受到http请求的时候交由UrlRewrite里面的UrlRewrite处理。并且将get方式获得的参数加请求的URL一起传过去。
public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(context_BeginRequest); } void context_BeginRequest(object sender, EventArgs e) { HttpApplication app = (HttpApplication)sender; HttpUrlRewrite(app.Context); } public void HttpUrlRewrite(HttpContext context) { string url = context.Request.Url.AbsolutePath; //在这里判断如果是一般文件(图片文件,css文件等)则直接跳转 if (url.IndexOf(".") > -1 && !(url.IndexOf(".ashx") > -1)) { return; } string physicUrl = "~/"; string[] keys = url.Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (keys.Length == 0 || keys.Length == 1) { physicUrl += "Default.ashx"; } else { string modulename = GetModuleName(keys[0]);//模块名称 string pagename = GetPageName(keys[1]);//页面名称 if (!string.IsNullOrEmpty(modulename)) { physicUrl += modulename + "/"; } physicUrl += pagename + ".ashx"; } context.RewritePath(physicUrl, null, string.Format("url={0}&{1}", url, context.Request.Url.Query)); } //在此判断页面名 internal string GetPageName(string name) { switch (name) { case "Default": return "Default"; case "Action": return "Action"; case "AdminDefault": return "AdminDefault"; } return name; } //在此判断模块名称 internal string GetModuleName(string name) { switch (name) { case "Home": return string.Empty; case "Admin": return "Admin"; } return name; }
在此处理这段URL并找到其物理路径通过HttpContext的RewritePath方法来跳转到该页面处理。
好!到了这一步已经可以进入对页面的处理模块了!页面类继承抽象类HttpCustom类,而HttpCustom类继承IHttpHandler用于处理http请求。
public abstract class HttpCustom : System.Web.IHttpHandler { #region IHttpHandler 成员 private HttpRequest _request; public HttpRequest Request { get { return _request; } set { _request = value; } } private HttpResponse _response; public HttpResponse Response { get { return _response; } set { _response = value; } } public bool IsReusable { get { return true; } } bool IsDocFromCache = false; public virtual void ProcessRequest(System.Web.HttpContext context) { //这里是接收请求的入口,我们将在这里自定义页面生命周期 Page_Init(context);//参数初始化 Page_PreLoad();//预加载,初始化html if (IsDocFromCache) { Page_OnCache();//缓存时,个别需要处理,如用户名 } else { Page_Load();//这个具体分给ashx处理 } Page_PreEnd();//输出前做点什么 Page_End();//输出html } private void Page_Init(HttpContext context) { this._request = context.Request; this.Response = context.Response; } private void Page_PreLoad() { } protected abstract void Page_Load(); protected virtual void Page_OnCache() { } private void Page_PreEnd() { } private void Page_End() { } #endregion }
因为做测试我在重载的Page_Load方法里面所以输出一下文字已表示请求到的页面。
public class AdminDefault : HttpCustom { protected override void Page_Load() { this.Response.Write("this is adminDefault page!"); foreach (string key in Request.QueryString.Keys) { this.Response.Write("<br/>"); this.Response.Write(Request.QueryString[key]); } } }
好到这里已经完成了!我们来测试下运行项目,在浏览器中输入http://localhost:3801/Admin/AdminDefault?t=3&fg=afsdf,然后页面出来了如下图:
当然要一个完整的后面还有很多步骤,如页面的动态化生成,缓存,数据库(要真要继续弄下去打算用nhibernate来进行数据操作)等!
附源码:下载