一.先來看個框架例子:(這個是網上收集到的)
第一步:創建一個類庫ClassLibrary831。
第二步:編寫一個類實現IHttpModule接口
class TestModule:IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
}
}
第三步:在Init事件中注冊EndRequest事件,並實現事件處理方法
class TestModule:IHttpModule
{
public void Dispose(){}
public void Init(HttpApplication context)
{
context.EndRequest += new EventHandler(context_EndRequest);
}
void context_EndRequest(object sender, EventArgs e)
{
HttpApplication ha = (HttpApplication)sender;
ha.Response.Write("<!--這是每個頁面都會動態生成的文字。--grayworm-->");
}
}
第四步:在Web.Conofig中注冊一下這個HttpModule模塊
<httpModules>
<add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>
</httpModules>
name:模塊名稱,一般是類名
type:有兩部分組成,前半部分是命名空間和類名組成的全名,后半部分是程序集名稱,如果類是直接放在App_Code文件夾中,那程序名稱是App_Code。
這樣在Web站點是添加該類庫的引用后,運行每個頁面,會發現其源文件中都會加入“<!--這是每個頁面都會動態生成的文字。--grayworm-->”這句話。同樣的方法你也可以在其中加入JS代碼。
2、身份檢查
大家在作登錄時,登錄成功后,一般要把用戶名放在Session中保存,在其它每一個頁面的Page_Load事件中都檢查Session中是否存在用戶名,如果不存在就說明用戶未登錄,就不讓其訪問其中的內容。
在比較大的程序中,這種做法實在是太笨拙,因為你幾乎要在每一個頁面中都加入檢測Session的代碼,導致難以開發和維護。下面我們看看如何使用HttpModule來減少我們的工作量
由於在這里我們要用到Session中的內容,我們只能在AcquireRequestState和PreRequestHandlerExecute事件中編寫代碼,因為在HttpModule中只有這兩事件中可以訪問Session。這里我們選擇PreRequestHandlerExecute事件編寫代碼。
第一步:創建一個類庫ClassLibrary831。
第二步:編寫一個類實現IHttpModule接口
class TestModule:IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
}
}
第三步:在Init事件中注冊PreRequestHandlerExecute事件,並實現事件處理方法
class AuthenticModule:IHttpModule
{
public void Dispose(){}
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication ha = (HttpApplication)sender;
string path = ha.Context.Request.Url.ToString();
int n = path.ToLower().IndexOf("Login.aspx");
if (n == -1) //是否是登錄頁面,不是登錄頁面的話則進入{}
{
if (ha.Context.Session["user"] == null) //是否Session中有用戶名,若是空的話,轉向登錄頁。
{
ha.Context.Response.Redirect("Login.aspx?source=" + path);
}
}
}
}
第四步:在Login.aspx頁面的“登錄”按鈕中加入下面代碼
protected void Button1_Click(object sender, EventArgs e)
{
if(true) //判斷用戶名密碼是否正確
{
if (Request.QueryString["source"] != null)
{
string s = Request.QueryString["source"].ToLower().ToString(); //取出從哪個頁面轉來的
Session["user"] = txtUID.Text;
Response.Redirect(s); //轉到用戶想去的頁面
}
else
{
Response.Redirect("main.aspx"); //默認轉向main.aspx
}
}
}
第五步:在Web.Conofig中注冊一下這個HttpModule模塊
<httpModules>
<add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>
</httpModules>
第二步:編寫一個類實現IHttpModule接口
class TestModule:IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
}
}
第三步:在Init事件中注冊EndRequest事件,並實現事件處理方法
class TestModule:IHttpModule
{
public void Dispose(){}
public void Init(HttpApplication context)
{
context.EndRequest += new EventHandler(context_EndRequest);
}
void context_EndRequest(object sender, EventArgs e)
{
HttpApplication ha = (HttpApplication)sender;
ha.Response.Write("<!--這是每個頁面都會動態生成的文字。--grayworm-->");
}
}
第四步:在Web.Conofig中注冊一下這個HttpModule模塊
<httpModules>
<add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>
</httpModules>
name:模塊名稱,一般是類名
type:有兩部分組成,前半部分是命名空間和類名組成的全名,后半部分是程序集名稱,如果類是直接放在App_Code文件夾中,那程序名稱是App_Code。
這樣在Web站點是添加該類庫的引用后,運行每個頁面,會發現其源文件中都會加入“<!--這是每個頁面都會動態生成的文字。--grayworm-->”這句話。同樣的方法你也可以在其中加入JS代碼。
2、身份檢查
大家在作登錄時,登錄成功后,一般要把用戶名放在Session中保存,在其它每一個頁面的Page_Load事件中都檢查Session中是否存在用戶名,如果不存在就說明用戶未登錄,就不讓其訪問其中的內容。
在比較大的程序中,這種做法實在是太笨拙,因為你幾乎要在每一個頁面中都加入檢測Session的代碼,導致難以開發和維護。下面我們看看如何使用HttpModule來減少我們的工作量
由於在這里我們要用到Session中的內容,我們只能在AcquireRequestState和PreRequestHandlerExecute事件中編寫代碼,因為在HttpModule中只有這兩事件中可以訪問Session。這里我們選擇PreRequestHandlerExecute事件編寫代碼。
第一步:創建一個類庫ClassLibrary831。
第二步:編寫一個類實現IHttpModule接口
class TestModule:IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
}
}
第三步:在Init事件中注冊PreRequestHandlerExecute事件,並實現事件處理方法
class AuthenticModule:IHttpModule
{
public void Dispose(){}
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication ha = (HttpApplication)sender;
string path = ha.Context.Request.Url.ToString();
int n = path.ToLower().IndexOf("Login.aspx");
if (n == -1) //是否是登錄頁面,不是登錄頁面的話則進入{}
{
if (ha.Context.Session["user"] == null) //是否Session中有用戶名,若是空的話,轉向登錄頁。
{
ha.Context.Response.Redirect("Login.aspx?source=" + path);
}
}
}
}
第四步:在Login.aspx頁面的“登錄”按鈕中加入下面代碼
protected void Button1_Click(object sender, EventArgs e)
{
if(true) //判斷用戶名密碼是否正確
{
if (Request.QueryString["source"] != null)
{
string s = Request.QueryString["source"].ToLower().ToString(); //取出從哪個頁面轉來的
Session["user"] = txtUID.Text;
Response.Redirect(s); //轉到用戶想去的頁面
}
else
{
Response.Redirect("main.aspx"); //默認轉向main.aspx
}
}
}
第五步:在Web.Conofig中注冊一下這個HttpModule模塊
<httpModules>
<add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>
</httpModules>
接下來聯系項目實例:
(1)控制器:
1 [ HttpPost] 2 public ActionResult LogOn(LogOnModel model, string returnUrl) 3 { 4 if (!ModelState.IsValid) 5 { 6 return View(model); 7 } 8 9 //驗證注冊信息 10 //string localCode = System.Configuration.ConfigurationManager.AppSettings["LocalCode"]; 11 //if (localCode == null || localCode != "98D4A31D9BC700F0B11F2679E9316814BA3DED4CF7C77EBA")//開發期間本地跳過注冊程序 12 //{ 13 // if (!Auth()) 14 // { 15 // ModelState.AddModelError("", "系統未注冊,無法登錄!"); 16 // return View(model); 17 // } 18 //} 19 20 //AccountRepository accountRp = new AccountRepository(); 21 var userinfo = new NewUserRepository().GetUser(model.UserName, model.Password); 22 if (userinfo != null ) 23 { 24 string onlineName = userinfo.UserID + userinfo.UserName; 25 string loginIp = HttpContext.Request.UserHostAddress; 26 27 OnlineUser nowOnlineUser = UserOnlineModule .OnlineList.Find(e => e.UserName == onlineName); 28 if (nowOnlineUser != null ) 29 { 30 if (nowOnlineUser.LoginIp != loginIp) 31 { 32 ModelState.AddModelError( "", "所登錄帳號已在其他地址登錄." ); 33 return View(model); 34 } 35 } 36 else 37 { 38 nowOnlineUser = new OnlineUser (); 39 nowOnlineUser.UserName = onlineName; 40 nowOnlineUser.LoginTime = DateTime.Now; 41 nowOnlineUser.LastTime = DateTime.Now; 42 nowOnlineUser.LoginIp = HttpContext.Request.UserHostAddress; 43 nowOnlineUser.LastActionUrl = HttpContext.Request.Url.PathAndQuery; 44 nowOnlineUser.SessionID = HttpContext.Session.SessionID.ToUpper(); 45 nowOnlineUser.IsGuest = false; 46 UserOnlineModule.OnlineList.Add(nowOnlineUser); 47 } 48 49 string userData = userinfo.UserID + "," + userinfo.UserName + "," + userinfo.DepNO + "," + userinfo.PID; 50 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, 51 userData, 52 DateTime.Now, 53 DateTime.Now.AddMinutes(30), 54 false, 55 userData, 56 FormsAuthentication.FormsCookiePath); 57 58 // Encrypt the ticket. 59 string encTicket = FormsAuthentication .Encrypt(ticket); 60 61 var cookietemp = new HttpCookie( FormsAuthentication.FormsCookieName, encTicket); 62 //cookietemp.Expires = DateTime.Now.AddMinutes(20); //設置cookies的過期時間 63 // Create the cookie. 64 Response.Cookies.Add(cookietemp); 65 //FormsAuthentication.SetAuthCookie(userinfo.UserID + "," + userinfo.UserName + "," + empid + "," + userinfo.DepNO, false); 66 //在后續的函數中,通過例如UserID = HttpContext.Current.User.Identity.Name.Split(',')[0];的方式獲得需要的用戶信息元數據 67 //還可以通過FormsAuthenticationTicket的方式,參見http://msdn.microsoft.com/en-us/library/system.web.security.formsauthenticationticket.aspx 68 //可以實現Cookie的加密等等,以后要實現。 69 if (!String .IsNullOrEmpty(returnUrl)) return Redirect(returnUrl); 70 else return RedirectToAction("Index", "Home"); 71 } 72 73 ModelState.AddModelError( "", "用戶帳號信息有誤,帳號或密碼錯誤." ); 74 return View(model); 75 }
(2)
IHttpModule接口:
1 public class UserOnlineModule : IHttpModule 2 { 3 #region IHttpModule 成員 4 5 public static List< OnlineUser> OnlineList = null ; 6 private System.Timers.Timer updateTimer; 7 //在線用戶活動超時:分鍾,默認10分鍾 8 private int timeOut = 10; 9 //設置計時器觸發周期:毫秒,默認1分鍾 10 private double timeInterval = 60000; 11 12 public void Init(HttpApplication context) 13 { 14 context.AuthenticateRequest += new EventHandler (context_AuthenticateRequest); 15 } 16 17 void context_AuthenticateRequest(object sender, EventArgs e) 18 { 19 if (OnlineList == null ) 20 OnlineList = new List <OnlineUser>(); 21 22 updateTimer = new System.Timers.Timer (); 23 updateTimer.AutoReset = true; 24 updateTimer.Elapsed += new System.Timers.ElapsedEventHandler (updateTimer_Elapsed); 25 updateTimer.Interval = timeInterval; 26 updateTimer.Start(); 27 } 28 29 void updateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 30 { 31 updateTimer.Stop(); 32 if (OnlineList.Count > 0) 33 OnlineList.RemoveAll(p => ( DateTime.Now - p.LastTime).Minutes >= timeOut); 34 updateTimer.Interval = timeInterval; 35 updateTimer.Start(); 36 } 37 38 public void Dispose() 39 { 40 41 } 42 #endregion 43 }
(3)記住需要在web.config文件里面注冊
一下這個HttpModule模塊(這個很重要,我剛開始就是沒弄這個,導致怎么也弄不出來)
< httpModules>
< add name ="OnlineList " type ="CoreLibrary.Helper.UserOnlineModule "/>
</ httpModules>
(4)至於視圖方面就很簡單了:
1 @Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.") 2 <div data-role="fieldcontain"> 3 @using (Html.BeginForm("LogOn", "Account", FormMethod.Post, new { @class = "form login" })) 4 { 5 @Html.LabelFor(m => m.UserName) 6 @Html.TextBoxFor(m => m.UserName, new { required="required",placeHolder="User Name"}) 7 @Html.ValidationMessageFor(m => m.UserName) 8 <br /> 9 @Html.LabelFor(m => m.Password) 10 @Html.PasswordFor(m => m.Password, new { required = "required", placeHolder = "Password" }) 11 @Html.ValidationMessageFor(m => m.Password) 12 13 <br /> 14 15 @Html.CheckBoxFor(m=>m.RememberMe) 16 @Html.LabelFor(m=>m.RememberMe) 17 <input type="submit" value="Log On" /> 18 19 } 20 </div>
好了,大致就是這樣了,如果有什么問題的話就歡迎交流探討。
