http://blog.csdn.net/fanbin168/article/details/49404233
很多时候,WebFrom页面,我们需要判断用户是否已经登陆了。假如有很多页面,难道我们要在每个页面都要做一次判断吗?
答案是否定的。 (除了这个例子外,我们还可以在Global.asax 或者HtppModule里面做)
1>使用PageBase类来实现
首先建立一个项目,在项目中添加一个类。这个类继承Page类。使他成为一个页面类,然后再这个类中写一个虚方法,这个需方法就实现用户是否已经登陆的验证。
然后让有需要做登陆验证的其他页面来继承这个类。
PageBase类。
[csharp] view plain copy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace 检查登陆验证
{
public class PageBase:System.Web.UI.Page //新建一个PageBase类,让它集成Page类。这样PageBase就是一个页面类了
{
protected virtual void Page_Load(object sender, EventArgs e)
{
//string s = Request.Path; //path:是获取请求的虚拟路径; 它的值是:/admin/Welcome.aspx
Uri uri = Request.Url;
string url = uri.AbsolutePath; // uri.AbsolutePath:是获取Uri的绝对路径; 它的值是:/admin/Welcome.aspx
//当请求admin目录下的文件的时候,就需要验证用户是否登陆(这样做的好处就是,将一些需要验证用户是否登陆的文件放到一个admin文件夹下,当用户请求这个文件夹下的文件的时候,我才做登陆验证,否则就不用验证了。)
if (url.ToLower().StartsWith("/admin"))
{
if (Session["UserName"] == null)
{
Response.Redirect("Login.aspx");
}
}
}
}
}
Welcome.aspx (因为这个类需要用户登陆后才能进入的。所有我就让这个类继承PageBase类)
Welcome.aspx文件
[html] view plain copy
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Welcome.aspx.cs" Inherits="检查登陆验证.admin.Welcome" %>
Welcome.aspx.cs文件
[csharp] view plain copy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace 检查登陆验证.admin
{
//注意这个Welcome类继承PageBase 而不是直接继承System.Web.UI.Page (PageBase类是继承System.Web.UI.Page 类的)
public partial class Welcome : PageBase
{
protected override void Page_Load(object sender, EventArgs e)
{
base.Page_Load(sender, e);//在这里调用一下父类的Page_Load方法
//在这里重写父类的Page_Load方法
}
}
}
Login.aspx (因为这个页面不需要验证是否登陆。所以不需要继承PageBasel类)
Login.aspx文件
[csharp] view plain copy
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="检查登陆验证.Login" %>
login.aspx.cs文件
[csharp] view plain copy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace 检查登陆验证
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void submit_Click(object sender, EventArgs e)
{
string vcode = this.Vcode.Text.Trim();
if (this.txtUserName.Text.Trim() == "zhangshan" && this.txtPassWord.Text.Trim() == "123456")
{
if (Session["ValidCode"] != null)
{ string ss=Session["ValidCode"].ToString();
if (vcode ==ss )
{
Session["UserName"] = "zhangshan";
Response.Redirect("Welcome.aspx");
}
}
}
}
}
}
赋送验证码ValidCodeashx.ashx
[csharp] view plain copy
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.SessionState;
namespace 检查登陆验证.ashx
{
///
public void ProcessRequest(HttpContext context)
{
//1.随即生成4位数字(及1000到9999之间的数字)
Random rdm = new Random();
int number = rdm.Next(1000, 10000);
context.Session["ValidCode"] = number.ToString();
CreateValidateGraphic(number.ToString(), context);
}
/// <summary>
/// 创建验证码的图片
/// </summary>
/// <param name="containsPage">要输出到的page对象</param>
/// <param name="validateNum">验证码</param>
public void CreateValidateGraphic(string validateCode, HttpContext context)
{
Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 12.0), 22);
Graphics g = Graphics.FromImage(image);
try
{
//生成随机生成器
Random random = new Random();
//清空图片背景色
g.Clear(Color.White);
//画图片的干扰线
for (int i = 0; i < 25; i++)
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
}
Font font = new Font("Arial", 12, (FontStyle.Bold | FontStyle.Italic));
System.Drawing.Drawing2D.LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height),
Color.Blue, Color.DarkRed, 1.2f, true);
g.DrawString(validateCode, font, brush, 3, 2);
//画图片的前景干扰点
for (int i = 0; i < 100; i++)
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
//画图片的边框线
g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
//保存图片数据
MemoryStream stream = new MemoryStream();
image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
//输出图片流
context.Response.Clear();
context.Response.ContentType = "image/jpeg";//设置报文头
context.Response.BinaryWrite(stream.ToArray());
}
finally
{
g.Dispose();
image.Dispose();
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
2>使用自定义特性来实现,验证用户是否已经登录
思路:首先定义一个验证用户是否已经登录的特性。然后再有需要验证用户是否登录的页面类中打上这个特性标签
首先定义一个特性
[csharp] view plain copy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;
namespace 检查登陆验证.Attributes
{
[AttributeUsage(AttributeTargets.Class)] //这个特性只能用于类
public class CheckLoginAttribute : Attribute //定义一个名字叫CheckLoginAttribute 的特性,用户检查用户是否已经登录
{
//我们知道在一个类上打上[CheckLogin] 就等于 new CheckLoginAttribute() 所以我们在这里定义了这个CheckLoginAttribute特性的不带参数的构造函数,在构造函数中判断用户是否已经登录。如果用户未登录,那么就跳到Login.aspx页面
public CheckLoginAttribute()
{
if (HttpContext.Current.Session["UserName"] == null)
{
HttpContext.Current.Response.Redirect("Login.aspx");
}
}
}
}
现在就来使用一下这个[CheckLogin]特性
[csharp] view plain copy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using 检查登陆验证.Attributes;
namespace 检查登陆验证.admin
{
[CheckLogin] //因这个Welcome页面只有用户登陆后才能访问,所以在这个页面类上打上验证用户是否登陆的[CheckLogin]特性标签,这样,用户每次访问这个页面的时候就会先执行CheckLogin类中的构造函数中的代码。构造函数中的代码就用户判断用户是否已经登陆,如果未登录就会跳到登录页面了
public partial class Welcome : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
3>使用HttpModule来实现
如果使用HttpModule来实现的话,最好将需要做登陆验证的页面文件,和不需要做登陆验证的页面文件放到不同的文件夹下。这样的话再HttpModule里面就可以做判断,如果访问这个需要做登陆验证的文件下的文件的时候,就做登陆验证。不需要做登陆验证的文件夹下的页面就可以跳过登陆验证了。
如果将不需要验证登陆的页面和需要验证登陆的页面放在同一个文件夹下的话,就不好做这样的判断。
因为如果所有的页面都做登陆验证的判断的话,如果没有登陆。Login.aspx的Session["UserName"]也是为空的,这样用户在没有登陆的情况下,就永远无法跳转到登陆页面。因为在跳到登陆页面的时候,页面初始化,执行HttpApplication里面的19个事件,就会又执行验证Session["UserName"]是否为空,如果为空,又重新定向,这样就永远重新定向下去。就无法跳转到页面了、
[csharp] view plain copy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using 检查登陆验证.Attributes;
namespace 检查登陆验证
{
public class CheckLoginModule : IHttpModule
{
public void Dispose()
{
//throw new NotImplementedException();
}
public void Init(HttpApplication context)
{
context.AcquireRequestState += context_AcquireRequestState;
//context.AcquireRequestState += new EventHandler(context_AcquireRequestState); 也可以这样祖册事件
}
void context_AcquireRequestState(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
//获取用户请求的url (AbsolutePath:获取Uri的绝对路径)
string url = application.Context.Request.Url.AbsolutePath;
//判断这个Url是不是以/admin开始的。 其实就是判断访问的页面是不是在admin这个文件夹下。 如果访问admin这个文件下的页面那我们就判断用户是否已经登陆。如果不是admin这个文件夹下的目录,那么我就不做登���判断
if (url.ToLower().StartsWith("/admin"))
{
if (HttpContext.Current.Session["UserNmae"] == null)
{
application.Response.Redirect("Login.aspx");
}
}
}
}
}
在Web.config文件下的 节点下添加以下内容
[html] view plain copy