隨著AJAX.NET BETA 2在今天發布,讓我們看到了AJAX與ASP.NET2.0緊密結合的快捷與高效,我們甚至可以無需寫一句JS代碼即可讓ASP.NET的網頁得到以往要花上數小時編寫的JS程式碼所實現的無刷新效果。而將這一切結合到ASP.NET也是那麼的容易,只要將控制項簡單地移到UPDATEPANEL控制項之內再設定幾個參數即可實現。但是,在體驗AJAX.NET帶給開發者便利的同時,也會發現AJAX.NET有時也不是十全十美。就像筆者近日遇到ASP.NET2.0的Login控制在UPDATEPANEL內當成功驗證用戶資訊後會刷新頁面的BUG,很顯然這是違背了AJAX無刷新的原則了,之後經過分析Login控制項內建的用戶驗證的方法發現如下程式碼:
private void AttemptLogin()
{
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控制項內執行轉向操作導致頁面刷新!
this.Page.Response.Redirect(this.GetRedirectUrl(), false);
}
}
}
透過分析AttemptLogin方法不難看出,當我們按下Login控制項的登入Button並成功驗證使用者資訊之後會執行一句Response.Redirect頁面轉向語句(即使沒有指定轉向頁也會執行這句程式碼,預設為當前頁) ,而正是因為執行了頁面的轉向而導致了頁面的刷新。當知道出錯的原因之後就好辦了,可能這時會有人說自訂控制項繼承Login控制項並重寫AttemptLogin方法就可以了,但除了自訂控制項之外還有沒有更簡單的方法呢?答案是肯定的,既然是內建的驗證機製造成頁面的刷新,那麼就索性不使用Login控制項的驗證處理,而使用自訂一個方法去處理驗證使用者身分。首先為了使用自訂的驗證方法,我們先找到Login控件,並將其轉換成模板,然後在模板內找到LoginButton這個控件,將CommandName="Login" 去掉,這樣控件就不再使用內建的方法去驗證使用者資訊了,跟著我們為LoginButton加上一個OnClick事件,程式碼如下:
protected void LoginButton_Click(object sender, EventArgs e)
{
//驗證使用者名稱及密碼是否正確
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控制項改造為成功驗證使用者資訊之後不再刷新了,這樣改造後的好處是不用像編寫自訂控制項那樣複雜,效果和原來的Login控制項是一模一樣的,也照樣能使用CreateUserWizard控制項所建立的使用者名稱進行驗證,而LoginStatus、LoginName等Login控制項相關的控制項也能如常使用。
PS:如果Login控制項驗證使用者資訊時出現PageRequestManagerParserErrorException錯誤,請檢查web.config是否有這句話:
<httpModules>
.....
<add name="ScriptModule" type="Microsoft.Web.UI.ScriptModule, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</httpModules>
感謝saucer提醒
http://www.cnblogs.com/aspxcn/archive/2006/11/07/552927.html