在ASP.NET 2.0中,新增加的membership provider功能,以及結合功能強大的一系列注冊,登陸控件,可以很方便地對用戶的登陸和權限等進行管理(參見<<ASP.Net 2.0登陸控件簡介>>)。
但是,可能大家會發現,ASP.NET 2.0自帶的這些登陸控件和membership的管理功能,默認的是和sql server 2005 express搭配使用的,那麼,如何改成使用SQL Server 2000或者是其他的數據源,如Access,Oracle等呢?如果自己想在應用中,另外重新寫一個對登陸用戶或者用戶權限等管理的應用,要如何修改呢?在本文中,將給出在ASP.Net 2.0中使用自定義provider,以配合登陸控件來實現一個簡單的登陸過程。
為了明白ASP.Net 2.0中的provider是如何工作的,首先看下下面的結構圖:
如果不想使用在Visual Studio 2005 beta 2中提供的SqlMembershipProvider,則只需要聲明自己的類,並且繼承MembershipProvider類就可以了。MembershipProvider類包含了與membership相關的方法和屬性。
在Solution Explorer中,使用"Add New item..",增加一個類,命名為AccessMembershipProvider.vb,並按系統提示,將其放到App_Code目錄中去。
接下來,引用相關的命名空間,並且寫出程序的框架如下:
Imports Microsoft.VisualBasic
Imports System.Data
Public Class AccessMembershipProvider
Inherits MembershipProvider
End Class
為了要使用自定義的provider,必須在web.config中進行相關的配置。可以新增加一個web.config文件,寫入如下的代碼:
<system.web>
<authentication mode="Forms"/>
<membership
defaultProvider="AccessMembershipProvider" >
<providers>
<add name="AccessMembershipProvider"
type="AccessMembershipProvider"
requiresQuestionAndAnswer="true"
connectionString="Provider=Microsoft.Jet.
OLEDB.4.0;Data Source=C:\NewMembershipProvider\
App_Data\Members.mdb;Persist Security
Info=False" />
</providers>
</membership>
</system.web>
其中,要留意如下幾點:
必須選擇驗證方式為"Forms"(authentication mode="forms").
通過使用<add>標簽,增加一個自定義的provider,名稱叫AccessMembershipProvider。
其中的requiresQuestionAndAnswer屬性,當其值為true時,指出在新注冊時,必須填寫提示問題和要回答的答案。
ConnectionString,指出要進行數據庫連接的連接串。
DefaultProvider屬性,指出系統默認使用哪一個provider,因為一個系統中可以設置多個provider.
在AccessMembershipProvider.vb中,增加以下的私有成員
Private connStr As String
Private comm As New OleDb.OleDbCommand
Private _requiresQuestionAndAnswer As Boolean
Private _minRequiredPassWordLength As Integer
並且增加Initialize()方法,代碼如下
Public Overrides Sub Initialize(ByVal name As String, ByVal config As System.Collections.Specialized.NameValueCollection)
’===retrives the attribute values set in
’web.config and assign to local variables===
If config("requiresQuestionAndAnswer") = "true" Then _
_requiresQuestionAndAnswer = True
connStr = config("connectionString")
MyBase.Initialize(name, config)
End Sub
當provider被裝載時,會調用Initialize()方法。剛才在web.config文件中,使用<add>標簽設置的各類屬性值,都能在這個方法中讀取。比如,可以通過使用config參數來讀取,上面的代碼中,就使用config("connectionString")來讀取數據庫連接字符串,並放到變量connStr變量中去。之後,再設置RequiresQuestionAndAnswer屬性,如下:
Public Overrides ReadOnly Property _
RequiresQuestionAndAnswer() _
As Boolean
Get
If _requiresQuestionAndAnswer = True Then
Return True
Else
Return False
End If
End Get
End Property
要注意,必須設置該屬性的值,否則,在CreateUserWizard控件中,則不會顯示密碼提示問題和密碼提示答案兩個文本框。
接下來,我們可以開始編寫新建用戶的代碼了,CreateUser()方法的代碼如下:
Public Overrides Function CreateUser(ByVal username As String, ByVal password As String, ByVal email As String, ByVal passwordQuestion As String, ByVal passWordAnswer As String, ByVal isApproved As Boolean, ByVal providerUserKey As Object, ByRef status As System.Web.Security.MembershipCreateStatus) As System.Web.Security.MembershipUser
Dim conn As New OleDb.OleDbConnection(connStr)
Try
conn.Open()
Dim sql As String = "INSERT INTO Membership VALUES (" & _
"@username, @passWord, @email, " & _
" @passwordQuestion, @passWordAnswer )"
Dim comm As New OleDb.OleDbCommand(sql, conn)
comm.Parameters.AddWithValue("@username", username)
comm.Parameters.AddWithValue("@password", passWord)
comm.Parameters.AddWithValue("@email", email)
comm.Parameters.AddWithValue("@passwordQuestion", passWordQuestion)
comm.Parameters.AddWithValue("@passwordAnswer", passWordAnswer)
Dim result As Integer = comm.ExecuteNonQuery()
conn.Close()
status = MembershipCreateStatus.Success
Dim user As New MembershipUser("AccessMembershipProvider", username, Nothing, email, passWordQuestion, Nothing, True, False, Now, Nothing, Nothing, Nothing, Nothing)
Return user
Catch ex As Exception
status = MembershipCreateStatus.UserRejected
Return Nothing
End Try
End Function
我們解讀一下上面的代碼,首先,我們往數據庫插入了一條記錄,在新增用戶成功後,我們必須返回一個狀態信息status(該status時在傳入時以ByRef status As System.Web.Security.MembershipCreateStatus方式傳入),並且我們要返回一個MembershipUser的類的實例,因此,我們以這樣的方式返回其實例:
Dim user As New MembershipUser("AccessMembershipProvider", username, Nothing, email, passWordQuestion, Nothing, True, False, Now, Nothing, Nothing, Nothing, Nothing)
其中,使用到MembershipUser類的方法的構造函數有很多,具體的可以查看MSDN,在這裡我們只用到了username,email,passWordQuestion,createdate(帳號創建日期,這裡使用NOW)。
而在登陸頁面裡,為了判斷是否為合法用戶登陸,則需要編寫如下代碼:
Public Overrides Function ValidateUser( _
ByVal username As String, _
ByVal passWord As String) As Boolean
Dim conn As New OleDb.OleDbConnection(connStr)
Try
conn.Open()
Dim sql As String = _
"Select * From Membership WHERE " & _
"username=@username AND password=@passWord"
Dim comm As New OleDb.OleDbCommand(sql, conn)
comm.Parameters.AddWithValue("@username", _
username)
comm.Parameters.AddWithValue("@passWord", _
passWord)
Dim reader As OleDb.OleDbDataReader = _
comm.ExecuteReader
If reader.HasRows Then
Return True
Else
Return False
End If
conn.Close()
Catch ex As Exception
Console.Write(ex.ToString)
Return False
End Try
End Function
就這樣,一個簡單的自定義provider就完成了,可以搭配登陸,注冊等控件進行使用了。運行程序,首先是出現用戶注冊的頁面,當用戶成功注冊後,則會將用戶引導到登陸頁面,如下圖所示: