在“許可權登入”一篇中我們介紹了如何使用微軟最新的許可權特性,通過在設定檔中聲明簡單的許可權可以達到控制登入使用者和匿名使用者的目的,同時還教會大家如何使用Login控制項的Authentication事件進行登入。但是,事件中的驗證代碼還是需要你來完成的。作為快速開發的VS IDE,微軟有沒有為我們提供更簡單的方法呢?答案是“有的”。今天就給出一個完整的,幾乎不用編寫任何代碼的簡單登入、註冊和密碼遺忘的功能的頁面。同時為了對比,
首先建立一個WebSite項目(必須是WebSite,否則無法正常產生資料和使用內建函數!),然後建立以下3個頁面:Default.aspx(一個Login控制項),Register.aspx(一個CreateUserWizard控制項)和一個ForgetPassword.aspx(一個密碼遺忘控制項:PasswordRecovery)。把Default設定成預設起始頁,然後添加以下代碼到web.config:
<location path="Default2.aspx">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
<location path="ForgetPassword.aspx">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<authentication mode="Forms">
<forms path="/" timeout="60" slidingExpiration="true" loginUrl="Default.aspx"/>
</authentication>
<authorization>
<allow users="*"/>
<deny users="?"/>
</authorization>
同時,將您的Login控制項轉成一個Template的模式(允許自訂樣式,比如添加一些其它控制項等),添加一個“Register”和“Forget Password”LinkButton,指定其PostBackUrl,以便使其點擊成功跳轉到註冊和密碼遺忘的頁面:
<asp:Login runat="server"
onauthenticate="Login1_Authenticate">
<LayoutTemplate>
<table cellpadding="1" cellspacing="0" style="border-collapse:collapse;">
<tr>
<td>
<table cellpadding="0">
<tr>
<td align="center" colspan="2">
Log In</td>
</tr>
<tr>
<td align="right">
<asp:Label runat="server" AssociatedControlID="UserName">User Name:</asp:Label>
</td>
<td>
<asp:TextBox runat="server"></asp:TextBox>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="UserName" ErrorMessage="User Name is required."
ToolTip="User Name is required." ValidationGroup="Login1">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td align="right">
<asp:Label runat="server" AssociatedControlID="Password">Password:</asp:Label>
</td>
<td>
<asp:TextBox runat="server" TextMode="Password"></asp:TextBox>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="Password" ErrorMessage="Password is required."
ToolTip="Password is required." ValidationGroup="Login1">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td colspan="2">
<asp:CheckBox runat="server" Text="Remember me next time." />
</td>
</tr>
<tr>
<td align="center" colspan="2" style="color:Red;">
<asp:Literal runat="server" EnableViewState="False"></asp:Literal>
</td>
</tr>
<tr>
<td align="left">
<asp:Button runat="server" CommandName="Login" Text="Log In"
ValidationGroup="Login1" />
</td>
<td align="right">
<asp:LinkButton runat="server" PostBackUrl="~/Register.aspx">Register Now</asp:LinkButton>
<asp:LinkButton runat="server"
PostBackUrl="~/ForgetPassword.aspx">Forget Password</asp:LinkButton>
</td>
</tr>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
</asp:Login>
在Register中放上一個CreateUserWizard控制項。在ForgetPassword頁面放上一個PasswordRecovery控制項。同時在web.config中添加以下配置(位於<system.web>節點外):
<system.net>
<mailSettings>
<smtp from="發送方地址xxx@abc.com" deliveryMethod="Network">
<network host="smtp伺服器位址(smtp.xx.xx)" userName="登入使用者名稱" password="口令" defaultCredentials="伺服器要求驗證" />
</smtp>
</mailSettings>
</system.net>
同時對於PasswordRecovery控制項中作如下定義:
<asp:PasswordRecovery runat="server" >
<MailDefinition Subject="郵件主題" />
</asp:PasswordRecovery>
基本上這樣,一個非常簡單的註冊功能的多頁面“項目”就完成了。簡單吧。下面我們分析它的原理:
1、首先看Default.aspx頁面部分:如果是WebSite工程,當放入一個Login的控制項的時候,它會在根目錄的一個叫“APP_DATA”的特別檔案夾裡(如果看不到請右鍵項目,選擇添加ASP.NET檔案夾,選擇即可)建立一個ASPNETDB.MDF資料庫檔案。並且建立了相關的表以便後續的使用者註冊等操作。
2、在Register.aspx頁面中存在一個CreateuserWizard控制項,該控制項一旦當使用者輸入使用者名稱等註冊資訊之後,自動觸發CreatingUser事件,同時調用Membership.CreateUser內建類把資訊逐一寫入那個自動產生的資料庫中,其函式宣告如下:
public static MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, out MembershipCreateStatus status);
其它的參數可以通過英文名字就逐一得知,我就不羅嗦了;這裡需要注意兩個特別的參數:“isApproved”是表示是否將該使用者停用;“MembershipCreateStatus”是一個枚舉,用於報告建立的情況(如果成功,將會是Success)。您完全可以在“CreateUserWizard1_CreateUserError”事件中通過“e.CreateUserError”來擷取失敗的資訊,做特殊處理。
3、在ForgetPassword.aspx頁面中,首先你輸入一個使用者名稱,系統在VerfyingUser事件中調用Membership.GetUser(string username)獲得一個MembershipUser的執行個體。如果不存在,則表示錯誤,自動讓e.Cancel = true(取消下一步操作)。如果成功,則e.Cancel=false進入下一步,同時擷取MemberShipUser的Answer(沒有直接提供屬性訪問)和你輸入的進行比較,對則發送email(自動讀取<system.net>的節點中的內容,對應如下代碼):
SmtpClient s = new SmtpClient();
MailMessage ms = new MailMessage();
ms.From = new MailAddress("發送方");
ms.To.Add(new MailAddress("接收方"));
ms.Subject = "郵件主題";
ms.Body = "郵件內文";
s.DeliveryMethod = SmtpDeliveryMethod.Network; //發送方式
s.Host ="smtp.xxx.xxx";
s.Credentials = new NetworkCredential("發送方信箱使用者名", "口令");
s.Send(ms);