今天簡單的作下HttpHandler的練習:只有登陸用戶才能下載images下地圖片文件(Session中標識是否登陸),若是用戶沒有登陸則首先重定向到登陸界面讓用戶登陸,用戶登陸成功則跳轉到下載列表頁面,下載連接固定寫好便可。若是登陸用戶是普通用戶則在圖片左上角加上「免費用試用」的字樣。javascript
1.首先創建名爲UserAuthority的數據庫,而後新建名爲T_Users的表,以下所示html
Level字段是記錄用戶的下載權限(」0」爲免費用戶和「1「爲收費用戶)。ErrorTimes爲記錄用戶錯誤登陸次數。LastErrorTimes則爲記錄用戶錯誤登陸的時間(若是錯誤登陸次數過多則會限制用戶登陸,防止惡意用戶不斷進行登陸)java
再進行操做以前,我如今T_Users表裏錄入些數據,以下:數據庫
2.建立名爲DataSetUser的強類型DataSet,而後將表T_Users拖到此文件裏面c#
其中,須要創建查詢使用的SQL語句dom
(GetDataByID(@ID) :SELECT ID, UserName, Password, [Level], ErrorTimes, LastErrorTimes FROM dbo.T_Users
where ID=@IDui
,GetDataByUserName :SELECT ID, UserName, Password, [Level], ErrorTimes, LastErrorTimes FROM dbo.T_Users
where UserName=@UserName spa
,IncErrorTimesById:Update T_Users set ErrorTimes=IsNULL(ErrorTimes,0)+1,LastErrorTimes=getDate() whereID=@ID.net
ResetErrorTimesById):UPDATE T_Users set ErrorTimes=0 where ID=@IDcode
3.創建所需頁面。
(1).Login.aspx
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using 用戶權限下載.DAL.DataSetUserTableAdapters; namespace 用戶權限下載 { public partial class Login : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) {
try { T_UsersTableAdapter adapter = new T_UsersTableAdapter(); var data = adapter.GetDataByUserName(TextBox1.Text); if (data.Count <= 0) { LabelErrorMsg.Text = "用戶名不存在!"; LabelErrorMsg.Visible = true; } var user = data.Single();//linq 時的Single方法,返回惟一一條數據,若是數據爲0或者多條,則拋出異常,把程序的錯誤扼殺在搖籃中 if (!user.IsErrorTimesNull() && !user.IsLastErrorTimesNull()) { double timeSpan = (DateTime.Now - user.LastErrorTimes).TotalMinutes;//計算當前時間和上次時間之間的差得分鐘數 if (user.ErrorTimes > 5 && timeSpan < 30) { LabelErrorMsg.Text = "您的輸入錯誤次數過多,請再30分鐘以後再嘗試登陸";//一旦被鎖定就不告訴訪問者密碼是對仍是錯
LabelErrorMsg.Visible = true; return; } } if (user.Password == TextBox2.Text) { Session["IsLoginornot"] = true; Session["UserID"] = user.ID; adapter.ResetErrorTimesById(user.ID);
string verCode = Session["Code"].ToString(); LabelErrorMsg.Visible = false; if (verCode != TextBox3.Text) { LabelVerCode.Text = "驗證碼錯誤"; LabelVerCode.Visible = true; // return; } else { Response.Redirect("DownLoadList.htm"); } Response.Redirect("DownLoadList.htm"); } else {
//int errorTimes=user.ErrorTimes+1;//可直接寫到強類型DataSet那裏 LabelErrorMsg.Text = "密碼錯誤,請從新輸入";//注意數據庫值爲null的問題 adapter.IncErrorTimesById(user.ID);//增長防暴力破解,重複錯誤五次,就鎖定帳戶半個小時(錯誤次數,上次所悟時間) LabelErrorMsg.Visible= true; } }
catch (Exception) { } } }
(2)圖片下載頁面 DownloadList.htm
和此頁面的HTML代碼
<!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> <title></title> </head> <body> <a href="DownloadPic.ashx?FileName=1.jpg">One</a><br /> <a href="DownloadPic.ashx?FileName=2.jpg">Two</a><br /> <a href="DownloadPic.ashx?FileName=3.jpg">Three</a><br /> </body> </html>
(3)若是用戶還沒登陸,會提示登陸並轉到RedirectToLogin.htm
HTML代碼:
<!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> <title></title> <script type="text/javascript"> var leftSeconds = 4; setInterval(function () { if (leftSeconds <= 0) { window.location.href = "Login.aspx"; } document.getElementById("leftDiv").innerText = leftSeconds; leftSeconds--; }, 1000); </script> </head> <body> 因爲您還沒登陸,不能進行下一步操做,本頁面在<div id="leftDiv">0</div>秒後跳轉到登陸頁面<br/> <a href="Login.aspx">點擊這裏能夠直接跳轉到登陸頁面</a> </body> </html>
(4)創建圖片下載的過程的代碼(動態生成JPEG圖片而後彈出對話框讓用戶下載,文件名爲圖片名),先創建名爲DownloadPic.ashx 的文件
using System; using System.Collections.Generic; using System.Linq; using System.Web; using 用戶權限下載.DAL.DataSetUserTableAdapters; using System.Drawing; using System.Drawing.Imaging; using System.Web.SessionState; namespace 用戶權限下載 { /// <summary> /// DownloadPic 的摘要說明 /// </summary> public class DownloadPic : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { if (context.Session["IsLoginornot"] == null) { context.Response.Redirect("RedirectToLogin.htm");//跳轉到RedirectToLogin頁面,3秒後或直接點擊進入Login.aspx頁面 } else { string filename = context.Request["FileName"]; context.Response.ContentType = "images/JPEG"; string encodeFileName = HttpUtility.UrlEncode(filename); context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename=\"{0}\"", encodeFileName)); int userId = (int)context.Session["UserID"]; T_UsersTableAdapter adapter = new T_UsersTableAdapter(); var data = adapter.GetDataByID(userId); var user = data.Single(); if (user.Level == 0) { using (Bitmap bitmap = new Bitmap(context.Server.MapPath("images/") + filename)) { using (Graphics g = Graphics.FromImage(bitmap)) { g.DrawString("免費用戶使用", new Font("宋體", 40), Brushes.Red, 0, 0); } bitmap.Save(context.Response.OutputStream, ImageFormat.Jpeg); } } else//收費用戶 { context.Response.WriteFile("images/" + filename);//有攻擊漏洞,重複錯誤5次,就鎖定帳戶半個小時。還有,避免DownloadPic.ashx?FileName=../DownloadPic.ashx.cs 的漏洞 } } } public bool IsReusable { get { return false; } } } }
4.增長驗證碼功能:
VerificationCode
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Drawing; namespace 用戶權限下載 { /// <summary> /// VerificationCode 的摘要說明 /// </summary> public class VerificationCode : IHttpHandler, System.Web.SessionState.IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType="images/JPEG"; using(Bitmap bitmap=new Bitmap(70,35)) { using(Graphics g=Graphics.FromImage(bitmap)) { Random rand=new Random(); int code=rand.Next(1000,9999); string strCode=Convert.ToString(code); HttpContext.Current.Session["Code"]=strCode; g.DrawString(strCode,new Font("宋體",20),Brushes.Red,0,0); bitmap.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); } } } public bool IsReusable { get { return false; } } } }