1. 去掉login按钮中的CommandName="Login"
2. 双击login按钮,重写登录按钮点击事件.login控件
如果没有登录,则跳转至login.aspx,同时将当前页面的URL传给ReturnUrl
登录以后,跳转回ReturnUrl指向的页面。获取ReturnUrl的方法Context.Request["ReturnUrl"] .
protected void LoginButton_Click(object sender, EventArgs e)
{
//验证用户名及密码是否正确
if (Membership.ValidateUser(this.lgLogin.UserName, lgLogin.Password))
{
//根据上面分析Login的验证机制,为客户端写上COOKIE.
FormsAuthentication.SetAuthCookie(lgLogin.UserName, lgLogin.RememberMeSet);
//验证成功后可在此作一些处理,如把Login控件隐藏起来
lgLogin.Visible = false;
StringBuilder _script = new StringBuilder();
_script.Append("<script type=\"text/javascript\">");
//_script.Append("var str=window.location.href;");
//_script.Append("var es=/ReturnUrl=/;");
//_script.Append("es.exec(str);");
//_script.Append("var right=RegExp.rightContext;");
//_script.Append("right=unescape(right);");
//_script.Append("pop_ChangedJobList();location.href=unescape(right);");
//pop_ChangedJobList()在js文件中,只是一句window.open("文件名"....);
_script.Append("pop_ChangedJobList();");
if (string.IsNullOrEmpty(Context.Request["ReturnUrl"]))
_script.Append("location.href=\"./ListUser.aspx\";");
else
_script.Append("location.href=\"." + Context.Request["ReturnUrl"] + "\";");
_script.Append("</script>");
Page.RegisterClientScriptBlock("", _script.ToString());
}
else
{
//由于不使用内置的验证机制,那么验证失败的处理要自己设置一下.
(lgLogin.FindControl("FailureText") as Literal).Text = "用户名或密码不正确,请重试!";
}
}
*************************************************************************************************
经过分析Login控件内置的用户身份信息验证的方法发现如下代码:
{
LoginCancelEventArgs args1 = new LoginCancelEventArgs();
this.OnLoggingIn(args1);
if (!args1.Cancel)
{
AuthenticateEventArgs args2 = new AuthenticateEventArgs();
this.OnAuthenticate(args2);
if (args2.Authenticated)
{
//用户信息验证成功后,为客户端写上COOKIE信息.
FormsAuthentication.SetAuthCookie(this.UserNameInternal, this.RememberMeSet);
this.OnLoggedIn(EventArgs.Empty);
//就是下面这句Response语句作怪,在UPDATEPANEL控件内执行转向操作导致Loign控件出错!
this.Page.Response.Redirect(this.GetRedirectUrl(), false);
}
}
}
通过分析AttemptLogin方法不难看出,当我们按下Login控件的登录Button并成功验证用户信息之后会执行一句Response.Redirect页面转向语句(即使没有指定转向页也会执行这句代码,默认为当前页),而UPDATEPANEL控件工作的机制决定了控件内执行转向语句必然会出错,因为转向语句调用Response.write()来输出转向代码,而UPDATEPANEL内是不能使用Response.write()输出代码的。当知道出错的原因之后就好办了,可能这时会有人说自定义控件继承Login控件并重写AttemptLogin方法就可以了,但除了自定义控件之外还有没有更简单的方法呢?答案是肯定的,既然是内置的验证机制与UPDATEPANEL有冲突,那么就索性不使用Login控件的验证处理,而使用自定义一个方法去处理验证用户身份。首先为了使用自定义的验证方法,我们先找到Login控件,并将其转换成模板,然后在模板内找到LoginButton这个控件,将CommandName="Login" 去掉,这样控件就不再使用内置的方法去验证用户信息了,跟着我们为LoginButton加上一个OnClick事件,代码如下:
{
//验证用户名及密码是否正确
if (Membership.ValidateUser(Login1.UserName, Login1.Password))
{
//根据上面分析Login的验证机制,为客户端写上COOKIE.
FormsAuthentication.SetAuthCookie(Login1.UserName, Login1.RememberMeSet);
//验证成功后可在此作一些处理,如把Login控件隐藏起来
Login1.Visible = false;
}
else
{
//由于不使用内置的验证机制,那么验证失败的处理要自己设置一下.
(Login1.FindControl("FailureText") as Literal).Text = "用户名或密码不正确,请重试!";
}
}
分析上面代码,其中因为Login控件要验证的用户信息都储存在SQL2005的ASPnetdb数据库的aspnet_membership表,这样我们只要使用Membership.ValidateUser这个方法就能轻松实现验证用户信息,当验证成功后,按照上面分析的AttemptLogin方法为客户端写上COOKIE,再设置一下验证失败的出错信息之后就轻松的把我们的Login控件改造为完全支持UPDATEPANEL的Login控件了,这样改造后的好处是不用像编写自定义控件那样复杂,并且效果和原来的Login控件是一模一样的,也照样能使用CreateUserWizard控件创建的用户名进行验证,而LoginStatus、LoginName等Login控件相关的控件也能如常使用。