Rocho.J

人脑是不可靠的, 随时记录感悟并且经常重复!

 

学习笔记---HttpApplication处理管道

当浏览器发送一个请求道服务器时, 实际上需要经过上图所示的流程, 该过程可以概括为:
"请求 ---> IIS ---> (检查IIS配置后)ASP.NET ---> HttContext ---> HttpApplication"
此时, 就进入了HttpApplication处理管道, 只要是ASP.NET的请求, 都会经过这个管道, 并且每一个请求都会经过这个处理管道. 而我们所熟悉的页面处理只是该流程第11步之后才开始执行的(Page_PreInit、Page_Init、Page_InitComplete、Page_PreLoad、Page_Load、Page_LoadComplete、Page_PreRender、Page_PreRenderComplete、SaveState、SaveStateComplete、Render), 而对于不同类型的文件(aspx、ashx、asmx等)则是在第7步之后进行选择的, 系统会根据文件扩展名, 为该文件映射对应的HttpHandler类.

 

我们实现HttpApplication的事件处理有两种方法: 即Global.aspx和IHttpModule两种方法, 更专业的方法是通过IHttpModule接口完成.

 

一: Globle.aspx
在Globle.aspx文件中, Application_Start方法将只能在应用程序调用第一个资源(如: 页面)时被执行, 且只能执行一次. 由于只能调用一次, 所以最好只设置静态数据(类成员), 不要设置实例数据, 因为实例数据只能有HttpAppliation类的第一个实例调用.
由于Application_Error可能发生在应用程序的任何阶段, 所以只有Application_end在应用程序生命周期最后会被调用且一定会被调用, 而Session_Start用于启动新会话, 注意: 只有当会话状态模式为"InProc"时, 才会引发Session_End时间, 其他模式(StateServer或SqlServer模式)将不会引发该事件.

//Default.aspx

代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!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 runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:label ID="lbl_time" runat="server" text="Label"></asp:label>
</div>
</form>
</body>
</html>

 

//Default.aspx.cs

代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}

protected void Page_PreRender(object sender, EventArgs e)
{
//DateTime time = DateTime.Parse(this.Context.Items["begin"].ToString());
DateTime time = DateTime.Parse(this.Application["begin"].ToString());
this.lbl_time.Text = "页面累计运行时间为: " + (DateTime.Now - time).TotalMilliseconds.ToString() + " 毫秒! ";
}
}

 

 //Global.asax

代码
<%@ Application Language="C#" %>

<script runat="server">

void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
DateTime begin = DateTime.Now;

//使用HttpContext状态管理传递参数, 此种方法只能用一次, 由于Application_Start只执行一次, 新的HttpApplication对象无法使用
//HttpContext context = HttpContext.Current;
//context.Items["begin"] = begin;

this.Application["begin"] = begin; //保存到全局状态
}

void Application_End(object sender, EventArgs e)
{
// Code that runs on application shutdown

}

void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs

}

void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started

}

void Session_End(object sender, EventArgs e)
{
// Code that runs when a session ends.
// Note: The Session_End event is raised only when the sessionstate mode
// is set to InProc in the Web.config file. If session mode is set to StateServer
// or SQLServer, the event is not raised.

}

</script>

 

二: 通过HttpModule接口完成:

2.1 通过HttpModule实现页面时间

//default.aspx

代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!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 runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lbl_pagetime" runat="server" Text="页面开销"></asp:Label>
</div>
</form>
</body>
</html>

 

//default.aspx.cs

代码
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(
5000);
}

protected void Page_PreRenderComplete(object sender, EventArgs e)
{
DateTime end
= DateTime.Now;
//HttpContext context = HttpContext.Current; //这个时候有页面对象, 可以直接通过this.Context属性获得


TimeSpan span
= end - this.Context.Timestamp;

this.lbl_pagetime.Text = string.Format("aspx中处理---页面执行时间为: {0}毫秒",span.TotalMilliseconds);
}
}

 

 //web.config

<system.web>
<httpModules>
<add name="PageTimeModule" type="Page.PageTime"/>
</httpModules>
</system.web>

 

 //App_Code中PageTime.cs

代码
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

namespace Page
{
/// <summary>
/// Summary description for PageTime
/// </summary>
public class PageTime : IHttpModule
{
//方法1:
DateTime begin;
DateTime end;

public PageTime()
{
//
// TODO: Add constructor logic here
//
}

#region IHttpModule Members

public void Dispose()
{
// 没有什么资源要清空
}

public void Init(HttpApplication application) //避免与HttpContext混淆, 改名
{
application.BeginRequest
+= new EventHandler(Application_BeginRequest); //在管道的第一个事件中注册
application.EndRequest += new EventHandler(Application_EndRequest); //管道的最后一个事件
}

void Application_EndRequest(object sender, EventArgs e)
{
//throw new NotImplementedException();
end = DateTime.Now;

TimeSpan span
= end - begin;

HttpContext context
= HttpContext.Current;

System.IO.TextWriter tw
= context.Response.Output;
tw.WriteLine(
string.Format("执行事件为: {0} 毫秒! ", span.TotalMilliseconds));

//方法2:
DateTime begin1 = context.Timestamp;
DateTime end1
= DateTime.Now;
TimeSpan span2
= end - begin;
tw.WriteLine(
string.Format("执行事件为: {0} 毫秒! ", span.TotalMilliseconds));
}

void Application_BeginRequest(object sender, EventArgs e)
{
//throw new NotImplementedException();
begin = DateTime.Now;
}

#endregion
}
}

 

 

 

 2.2 通过HttpModule实现用户登陆的状态管理

//LoginModel.cs, HttpModule接口实现类

代码
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

namespace Login
{
/// <summary>
/// Summary description for LoginModule
/// </summary>
public class LoginModule : IHttpModule
{
public LoginModule()
{
//
// TODO: Add constructor logic here
//
}

#region IHttpModule Members

public void Dispose()
{
//throw new NotImplementedException();
}

public void Init(HttpApplication application)
{
//throw new NotImplementedException();
application.AuthenticateRequest += new EventHandler(Application_AuthenticateRequest); //在管道中处理AuthenticateRequest事件
}

void Application_AuthenticateRequest(object sender, EventArgs e)
{
//throw new NotImplementedException();
HttpContext context = HttpContext.Current;

HttpCookie cookie
= context.Request.Cookies["UserName"]; //查看是否存在cookie
if (cookie != null)
{
//从cookie中取出名字, 放到context中, 以便在PreRequestHandlerExecute之后执行的页面处理事件中获得其中的值
string name = cookie.Value;
context.Items[
"loggedname"] = name;
}
}

#endregion
}
}

 

//default.aspx

代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!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 runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lbl_welcome" runat="server" Text="欢迎信息! "></asp:Label>
<asp:LinkButton ID="lbtn_loggout" runat="server" onclick="lbtn_loggout_Click">注销</asp:LinkButton>
<asp:HyperLink ID="hlnk_loggin" runat="server" NavigateUrl="~/Login.aspx">登陆</asp:HyperLink>
</div>
</form>
</body>
</html>

 

 //default.aspx.cs

代码
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (this.Context.Items["loggedname"] != null)
{
this.lbl_welcome.Text = string.Format("{0}, 您好! 欢迎回来! ", this.Context.Items["loggedname"]);
this.hlnk_loggin.Visible = false;
this.lbtn_loggout.Visible = true;
}
else
{
this.lbl_welcome.Text = string.Format("对不起, 您还没有登录! ");
this.lbtn_loggout.Visible = false;
this.hlnk_loggin.Visible = true;
}

}
protected void lbtn_loggout_Click(object sender, EventArgs e)
{
HttpCookie cookie
= this.Request.Cookies["UserName"]; //从请求里找cookie

cookie.Expires
= new DateTime(1900 ,1 , 1);

this.Response.SetCookie(cookie); //重新设置cookie
this.Response.Redirect("Login.aspx");
}
}

 

//login.aspx

代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>

<!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 runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<span>用户名: </span>
<asp:TextBox ID="txt_username" runat="server"></asp:TextBox><br/>
<span>密码: </span>
<asp:TextBox ID="txt_userpass" runat="server"></asp:TextBox><br />
<hr />
<asp:CheckBox ID="chkBox_remember" runat="server" Text="长期登陆" /><br />
<asp:LinkButton ID="lbtn_login" runat="server" onclick="lbtn_login_Click">登陆</asp:LinkButton>
</div>
</form>
</body>
</html>

 

 //login.aspx.cs

代码
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void lbtn_login_Click(object sender, EventArgs e)
{
string username = this.txt_username.Text;
string userpass = this.txt_userpass.Text;
if (username != null && userpass != null)
{
DAL.CalendarUser calendar
= new DAL.CalendarUser();
if (calendar.ValidateUserByProc(username, userpass))
{
HttpCookie cookie
= new HttpCookie("UserName");
cookie.Value
= username;

if (this.chkBox_remember.Checked == true)
{
cookie.Expires
= DateTime.Now.AddDays(7);
}

this.Response.Cookies.Add(cookie); //发cookie给可户端

this.Response.Redirect("default.aspx"); //重定向到default.aspx
}
}
}
}

 

//web.config

代码
<system.web>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="LoginModule" type="Login.LoginModule"/>
</httpModules>
</system.web>

 

 //DAL- Calendar.cs

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

namespace DAL
{
public class CalendarUser //DAL层通过SqlHelper访问数据库
{
//CalendarUser类提供关于日历用户的功能, 如: 创建用户
//DateTime是值类型, 而值类型没有与Sql中Null的对应, 加?表示可空类型, 即允许值类型为空
public int CreateUser(string username, string userpass, string email, DateTime? birthday)
{
int result = -1;

//定制的参数是根据SqlHelper的方法来选的
string connectionStr = CalendarHelper.ConnectionString;
string sqlText = @"insert into T_UserInfo(username, userpass,email,birthday)
values(@username,@userpass,@email,@birthday)
";
System.Data.CommandType cmdType
= System.Data.CommandType.Text;

System.Data.SqlClient.SqlParameter p_username
= new System.Data.SqlClient.SqlParameter("@username", System.Data.SqlDbType.NVarChar);
System.Data.SqlClient.SqlParameter p_userpass
= new System.Data.SqlClient.SqlParameter("@userpass",System.Data.SqlDbType.NVarChar);
System.Data.SqlClient.SqlParameter p_email
= new System.Data.SqlClient.SqlParameter("@email", System.Data.SqlDbType.NVarChar);
System.Data.SqlClient.SqlParameter p_birthday
= new System.Data.SqlClient.SqlParameter("@birthday",System.Data.SqlDbType.DateTime);

p_username.Value
= username;
p_userpass.Value
= userpass;
p_email.Value
= email;
p_birthday.Value
= birthday;

System.Data.SqlClient.SqlParameter[] paras
= new System.Data.SqlClient.SqlParameter[] { p_username, p_userpass, p_email, p_birthday };

result
= Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteNonQuery(connectionStr, cmdType,sqlText, paras);

return result;
}

public int CreateUserByProc(string username, string userpass, string email, DateTime? birthday)
{
//定制的参数是根据SqlHelper的方法来选的
string connectionStr = CalendarHelper.ConnectionString;
string sqlText = "SP_CreateUserProc";

System.Data.CommandType cmdType
= System.Data.CommandType.StoredProcedure;

System.Data.SqlClient.SqlParameter p_username
= new System.Data.SqlClient.SqlParameter("@username", System.Data.SqlDbType.NVarChar);
System.Data.SqlClient.SqlParameter p_userpass
= new System.Data.SqlClient.SqlParameter("@userpass", System.Data.SqlDbType.NVarChar);
System.Data.SqlClient.SqlParameter p_email
= new System.Data.SqlClient.SqlParameter("@email", System.Data.SqlDbType.NVarChar);
System.Data.SqlClient.SqlParameter p_birthday
= new System.Data.SqlClient.SqlParameter("@birthday", System.Data.SqlDbType.DateTime);
System.Data.SqlClient.SqlParameter p_return
= new System.Data.SqlClient.SqlParameter("@returnValue",System.Data.SqlDbType.Int);

p_username.Value
= username;
p_userpass.Value
= userpass;
p_email.Value
= email;
p_birthday.Value
= birthday;

p_return.Direction
= System.Data.ParameterDirection.ReturnValue;

System.Data.SqlClient.SqlParameter[] paras
= new System.Data.SqlClient.SqlParameter[] { p_username, p_userpass, p_email, p_birthday,p_return};

Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteNonQuery(connectionStr, cmdType, sqlText, paras);

//执行完存储过程后, 获取返回值
return (int)p_return.Value;
}

public bool ValidateUserByProc(string username, string userpass)
{
//定制的参数是根据SqlHelper的方法来选的
string connectionStr = CalendarHelper.ConnectionString;
string sqlText = "SP_ValidateUserByProc";

System.Data.CommandType cmdType
= System.Data.CommandType.StoredProcedure;

System.Data.SqlClient.SqlParameter p_username
= new System.Data.SqlClient.SqlParameter("@username", System.Data.SqlDbType.NVarChar);
System.Data.SqlClient.SqlParameter p_userpass
= new System.Data.SqlClient.SqlParameter("@userpass", System.Data.SqlDbType.NVarChar);
System.Data.SqlClient.SqlParameter p_return
= new System.Data.SqlClient.SqlParameter("@returnValue", System.Data.SqlDbType.Int);

p_username.Value
= username;
p_userpass.Value
= userpass;

p_return.Direction
= System.Data.ParameterDirection.ReturnValue;

System.Data.SqlClient.SqlParameter[] paras
= new System.Data.SqlClient.SqlParameter[] { p_username, p_userpass, p_return };

Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteNonQuery(connectionStr, cmdType, sqlText, paras);

//执行完存储过程后, 获取返回值
return (int)p_return.Value == 1; //返回1表示不存在, 即验证成功
}
}
}

 

//CalendarHelper.cs

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

namespace DAL
{
public class CalendarHelper //为DAL层提供连接串
{
private static readonly string connectionStr = System.Configuration.ConfigurationManager.ConnectionStrings["MsSql"].ConnectionString;

public static string ConnectionString //对外提供连接串
{
get
{
return connectionStr;
}
}

}
}

 

//SqlHelp.cs, 可以到网上去下载

posted on 2010-11-22 03:13  RJ  阅读(4008)  评论(0编辑  收藏  举报

导航