在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是如何運作的,首先看下面的結構圖:
Field Name Data Type Field Size Username (key) Text 8 Password Text 8 Email Text 50 passwordQuestion Text 50 passwordAnswer Text 50 |
Public Class ModifiedSqlMembershipProvider Inherits SqlMembershipProvider Public Overrides Function CreateUser (...) … End Function … End Class |
如果不想使用在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_DataMembers.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 inbute 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 = 真 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就完成了,可以搭配登陸,註冊等控制進行使用了。運行程序,首先是出現用戶註冊的頁面,當用戶成功註冊後,則會將用戶引導到登陸頁面,如下圖所示: