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

学习笔记---HttpApplication处理管道_第1张图片

当浏览器发送一个请求道服务器时, 实际上需要经过上图所示的流程, 该过程可以概括为:
"请求 ---> 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, 可以到网上去下载

你可能感兴趣的:(application)