在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 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就完成了,可以搭配登陆,注册等控件进行使用了。运行程序,首先是出现用户注册的页面,当用户成功注册后,则会将用户引导到登陆页面,如下图所示: