目的:
如果用户没有登录,就想访问某个网页(如请假单列表),我的程序现在是直接出错,因为其中的session("GH")为null,构建SQL语句时就出错了。当然,如果某些网页,没有使用session,那我的就正常体现出来(如请假单的增加)。接着,最后的保存时,出错,因为那时开始使用到session了,这下就被用户骂死了。
于是,我先在网页的Page_Load上加一句:
if (Session["GH"] == null)
{
Response.Redirect("../Public/Login.aspx");
}
这个效果还不错,但问题是,我要在每个网页上加这一句,比较不正常。于是开始追求使用Global.asax来实现对每个网页自动加上这一句。
先是把以上代码加到Session_Start,却发现一个用户只执行它一次。一旦Session的时间超出(在web.config中的<sessionState mode="StateServer" timeout="1"/>设置为1分钟,方便测试),就出错。出错后,网页地址栏直接输入登录界面,还会继续出错,因为这时Session已经丢失,所以申请网页一直走Session_Start,然后遇到Response.Redirect,又没走到头。
并且页面转向的方式也不对,如果我是通过AJAX申请的,结果就在DIV中显示登录界面。
后来,Response.Redirect改为Server.Execute,却又发现得不到Request.Params?
再试着把if (Session["GH"] == null)放到Application_BeginRequest中去,又出现“会话状态在此上下文不可用”。
几种方案试不成功,最后只好转向web.config中的authentication。配置成如下:
<authentication mode="Forms">
<forms name=".login" loginUrl="~/login/login.aspx" protection="All" timeout="90" path="/"></forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
但一试,就给我一个下马威,原来,我的Login.aspx中有引用Login.js,在调试状态下,会被认为是出错的(申请Login.js,又会引发转向Login.aspx,Login.aspx中又引用Login.js,如此循环)。
在web.config中加入这一段,并把Login.aspx中的相关资源都放在Login目录下,即可让调试也正常
<location path="Login">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
最后再测试是否符合条件:打开任何一个网页,都会跳到Login.aspx,打开Login.aspx不会跳了,输入正确帐号与密码,默认转到Main.aspx,其它的转到对应界面。时间超出时,打开出错,原来authentication的timeout与session的timeout必须保持一致(是指在我这种情况下,即用authentication的又用session的内容),否则是session时间超出了,而认证的居然还没超出。
另外一方面:还要避免调试时每次都转向Login.aspx,我先是在Session_Start中加入
System.Web.Security.FormsAuthentication.SetAuthCookie(Session["GH"], false);
但发现仍会转向Login.aspx。再把它移到Application_BeginRequest,这下是Session["GH"]出错,查后,才知道Application_BeginRequest在Session_Start之前,那时Session还没建立。改为变量就可以了。
System.Web.Security.FormsAuthentication.SetAuthCookie(sGH, false);
由于每个Application_BeginRequest都要执行这一步,也是很浪费,因此,我再加上一个标志。最后写成如下:
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (((System.Web.HttpApplication)(this)).Request.Url.Port != 80)
{
if (bReg == false)
{
bReg = true;
System.Web.Security.FormsAuthentication.SetAuthCookie(sGH, false);
}
}
}
OK,满意,通过!