HOW TO:實作自訂成員資格使用者

更新:2007 年 11 月

提供示範如何以自訂成員資格提供者擴充 MembershipUser 類別 (Class) 的範例。

雖然使用者 System.Web.Profile 提供了便利的機制供 Web 應用程式中每位使用者存放資訊,但應用程式的設計需要在 Membership 資料存放區中存放其他使用者資訊和使用者驗證資訊。如果是這種情況,您應該需要建置 (Build) 自訂成員資格提供者,以便存放和擷取資料存放區中的使用者驗證資訊和其他使用者值 (如需自訂成員資格提供者的範例,請參閱實作成員資格提供者)。此外,您可以擴充 MembershipUser 類別,使應用程式程式碼能使用加入的使用者值。

建立自訂成員資格使用者包含下列工作:

  • 建立繼承 MembershipUser 類別的類別。

  • 建立資料來源,以便存放驗證資訊和其他使用者資訊。

  • 建立資料來源的自訂成員資格提供者。自訂成員資格提供者將包含其他程式碼,使其可以接收自訂成員資格使用者型別的物件 (當做輸入使用),以及傳回自訂成員資格使用者型別的物件。

本主題中的範例將示範如何修改 HOW TO:成員資格提供者實作範例中的自訂成員資格提供者範例來支援自訂成員資格使用者實作 (Implementation)。

建立自訂成員資格使用者

藉由建立繼承 MembershipUser 類別的類別,然後包含公開 (Expose) 其他使用者值的屬性,您就可以建立自訂成員資格使用者。或者,您也可以在 MembershipUser 類別中加入方法和事件。

當呼叫 Membership 類別以建立自訂 MembershipUser 執行個體 (Instance) 時,只有 MembershipUser 類別定義的建構函式 (Constructor) 才會呼叫。如果 MembershipUser 實作包含其他建構函式多載,則只有專為呼叫自訂建構函式而撰寫的應用程式程式碼才能呼叫那些建構函式。

下列程式碼範例將示範簡單的自訂成員資格使用者,它繼承 MembershipUser 類別並提供兩個其他屬性:IsSubscriber (為布林值屬性,用以識別使用者是訂閱 Web 應用程式的服務還是電子報) 和 CustomerID (其包含個別客戶資料庫的唯一識別項)。

Imports System
Imports System.Web.Security


Namespace Samples.AspNet.Membership.VB

    Public Class OdbcMembershipUser
        Inherits MembershipUser

        Private _IsSubscriber As Boolean
        Private _CustomerID As String

        Public Property IsSubscriber() As Boolean
            Get
                Return _IsSubscriber
            End Get
            Set(ByVal value As Boolean)
                _IsSubscriber = value
            End Set
        End Property

        Public Property CustomerID() As String
            Get
                Return _CustomerID
            End Get
            Set(ByVal value As String)
                _CustomerID = value
            End Set
        End Property

        Public Sub New(ByVal providername As String, _
                       ByVal username As String, _
                       ByVal providerUserKey As Object, _
                       ByVal email As String, _
                       ByVal passwordQuestion As String, _
                       ByVal comment As String, _
                       ByVal isApproved As Boolean, _
                       ByVal isLockedOut As Boolean, _
                       ByVal creationDate As DateTime, _
                       ByVal lastLoginDate As DateTime, _
                       ByVal lastActivityDate As DateTime, _
                       ByVal lastPasswordChangedDate As DateTime, _
                       ByVal lastLockedOutDate As DateTime, _
                       ByVal isSubscriber As Boolean, _
                       ByVal customerID As String)

            MyBase.New(providername, _
                       username, _
                       providerUserKey, _
                       email, _
                       passwordQuestion, _
                       comment, _
                       isApproved, _
                       isLockedOut, _
                       creationDate, _
                       lastLoginDate, _
                       lastActivityDate, _
                       lastPasswordChangedDate, _
                       lastLockedOutDate)

            Me.IsSubscriber = isSubscriber
            Me.CustomerID = customerID

        End Sub

    End Class
End Namespace
using System;
using System.Web.Security;

namespace Samples.AspNet.Membership.CS
{
    public class OdbcMembershipUser : MembershipUser
    {
        private bool _IsSubscriber;
        private string _CustomerID;

        public bool IsSubscriber
        {
            get { return _IsSubscriber; }
            set { _IsSubscriber = value; }
        }

        public string CustomerID
        {
            get { return _CustomerID; }
            set { _CustomerID = value; }
        }

        public OdbcMembershipUser(string providername,
                                  string username,
                                  object providerUserKey,
                                  string email,
                                  string passwordQuestion,
                                  string comment,
                                  bool isApproved,
                                  bool isLockedOut,
                                  DateTime creationDate,
                                  DateTime lastLoginDate,
                                  DateTime lastActivityDate,
                                  DateTime lastPasswordChangedDate,
                                  DateTime lastLockedOutDate,
                                  bool isSubscriber,
                                  string customerID) :
                                  base(providername,
                                       username,
                                       providerUserKey,
                                       email,
                                       passwordQuestion,
                                       comment,
                                       isApproved,
                                       isLockedOut,
                                       creationDate,
                                       lastLoginDate,
                                       lastActivityDate,
                                       lastPasswordChangedDate,
                                       lastLockedOutDate)
        {
            this.IsSubscriber = isSubscriber;
            this.CustomerID = customerID;
        }



    }
}

如需修改 CreateUserWizard 控制項以包含成員資格使用者之其他使用者資訊的範例,請參閱 HOW TO:自訂 ASP.NET CreateUserWizard 控制項

建立成員資格使用者資料的資料存放區

您將需要提供資料存放區給成員資格功能所用的使用者驗證資訊,以及自訂成員資格使用者所使用的其他使用者資訊。

下列程式碼範例顯示的是一個查詢,您可以用以在 Microsoft Access 中執行,建立要存放驗證資訊的資料表和自訂成員資格使用者的屬性值。

CREATE TABLE Users
(
  PKID Guid NOT NULL PRIMARY KEY,
  Username Text (255) NOT NULL,
  ApplicationName Text (255) NOT NULL,
  Email Text (128) NOT NULL,
  Comment Text (255),
  Password Text (128) NOT NULL,
  PasswordQuestion Text (255),
  PasswordAnswer Text (255),
  IsApproved YesNo, 
  LastActivityDate DateTime,
  LastLoginDate DateTime,
  LastPasswordChangedDate DateTime,
  CreationDate DateTime, 
  IsOnLine YesNo,
  IsLockedOut YesNo,
  LastLockedOutDate DateTime,
  FailedPasswordAttemptCount Integer,
  FailedPasswordAttemptWindowStart DateTime,
  FailedPasswordAnswerAttemptCount Integer,
  FailedPasswordAnswerAttemptWindowStart DateTime,
  IsSubscriber YesNo,
  CustomerID Text (64)
)

建立自訂成員資格提供者

您將需要建立自訂成員資格提供者,它支援自訂成員資格使用者型別和自訂成員資格資料存放區。自訂成員資格提供者的 GetUserCreateUser 方法可以用於撰寫傳回自訂成員資格使用者型別的物件。自訂成員資格提供者的 UpdateUser 方法則可以用於撰寫接收自訂成員資格使用者型別的物件 (當做輸入使用)。

下列各節提供有關建立使用自訂成員資格使用者型別之自訂成員資格提供者的指引。這些範例建立在 HOW TO:成員資格提供者實作範例一文所提供的程式碼上,並使用本主題前面建立成員資格使用者資料的資料來源一節中的資料庫結構描述 (Database Schema)。

修改 GetUser 方法

當使用自訂成員資格使用者型別時,成員資格提供者的 MembershipProvider.GetUserMembershipProvider.GetUser 方法仍然必須傳回 MembershipUser 型別的物件。假如自訂成員資格使用者類別繼承 MembershipUser 類別,就會將自訂成員資格使用者型別的物件傳回為 GetUser 方法實作的傳回值。之後,應用程式程式碼就可以將傳回的 MembershipUser 轉型為自訂成員資格使用者型別,以便存取自訂成員資格使用者的其他成員,如下列程式碼範例所示。

下列程式碼範例顯示的是 HOW TO:成員資格提供者實作範例中之成員資格提供者範例修改過的 GetUser 方法 (及其支援的私用方法),其已更新為本主題前面建立自訂成員資格使用者一節中所述的傳回自訂成員資格使用者型別。

'
' MembershipProvider.GetUser(String, Boolean)
'

Public Overrides Function GetUser(ByVal username As String, _
                                  ByVal userIsOnline As Boolean) As MembershipUser

    Dim conn As OdbcConnection = New OdbcConnection(connectionString)
    Dim cmd As OdbcCommand = New OdbcCommand("SELECT PKID, Username, Email, PasswordQuestion," & _
          " Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate," & _
          " LastActivityDate, LastPasswordChangedDate, LastLockedOutDate" & _
          " FROM Users  WHERE Username = ? AND ApplicationName = ?", conn)

    cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username
    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName

    Dim u As OdbcMembershipUser = Nothing
    Dim reader As OdbcDataReader = Nothing

    Try
        conn.Open()

        reader = cmd.ExecuteReader()

        If reader.HasRows Then
            reader.Read()
            u = GetUserFromReader(reader)

            If userIsOnline Then
                Dim updateCmd As OdbcCommand = New OdbcCommand("UPDATE Users  " & _
                          "SET LastActivityDate = ? " & _
                          "WHERE Username = ? AND Applicationname = ?", conn)

                updateCmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = DateTime.Now
                updateCmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username
                updateCmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName

                updateCmd.ExecuteNonQuery()
            End If
        End If
    Catch e As OdbcException
        If WriteExceptionsToEventLog Then
            WriteToEventLog(e, "GetUser(String, Boolean)")

            Throw New ProviderException(exceptionMessage)
        Else
            Throw e
        End If
    Finally
        If Not reader Is Nothing Then reader.Close()

        conn.Close()
    End Try

    Return u
End Function


'
' MembershipProvider.GetUser(Object, Boolean)
'

Public Overrides Function GetUser(ByVal providerUserKey As Object, _
ByVal userIsOnline As Boolean) As MembershipUser

    Dim conn As OdbcConnection = New OdbcConnection(connectionString)
    Dim cmd As OdbcCommand = New OdbcCommand("SELECT PKID, Username, Email, PasswordQuestion," & _
          " Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate," & _
          " LastActivityDate, LastPasswordChangedDate, LastLockedOutDate" & _
          " FROM Users  WHERE PKID = ?", conn)

    cmd.Parameters.Add("@PKID", OdbcType.UniqueIdentifier).Value = providerUserKey

    Dim u As OdbcMembershipUser = Nothing
    Dim reader As OdbcDataReader = Nothing

    Try
        conn.Open()

        reader = cmd.ExecuteReader()

        If reader.HasRows Then
            reader.Read()
            u = GetUserFromReader(reader)

            If userIsOnline Then
                Dim updateCmd As OdbcCommand = New OdbcCommand("UPDATE Users  " & _
                          "SET LastActivityDate = ? " & _
                          "WHERE PKID = ?", conn)

                updateCmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = DateTime.Now
                updateCmd.Parameters.Add("@PKID", OdbcType.UniqueIdentifier).Value = providerUserKey

                updateCmd.ExecuteNonQuery()
            End If
        End If
    Catch e As OdbcException
        If WriteExceptionsToEventLog Then
            WriteToEventLog(e, "GetUser(Object, Boolean)")

            Throw New ProviderException(exceptionMessage)
        Else
            Throw e
        End If
    Finally
        If Not reader Is Nothing Then reader.Close()

        conn.Close()
    End Try

    Return u
End Function


'
' GetUserFromReader
'    A helper function that takes the current row from the OdbcDataReader
' and hydrates a MembershiUser from the values. Called by the 
' MembershipUser.GetUser implementation.
'

Private Function GetUserFromReader(ByVal reader As OdbcDataReader) As OdbcMembershipUser
    Dim providerUserKey As Object = reader.GetValue(0)
    Dim username As String = reader.GetString(1)
    Dim email As String = reader.GetString(2)

    Dim passwordQuestion As String = ""
    If Not reader.GetValue(3) Is DBNull.Value Then _
      passwordQuestion = reader.GetString(3)

    Dim comment As String = ""
    If Not reader.GetValue(4) Is DBNull.Value Then _
      comment = reader.GetString(4)

    Dim isApproved As Boolean = reader.GetBoolean(5)
    Dim isLockedOut As Boolean = reader.GetBoolean(6)
    Dim creationDate As DateTime = reader.GetDateTime(7)

    Dim lastLoginDate As DateTime = New DateTime()
    If Not reader.GetValue(8) Is DBNull.Value Then _
      lastLoginDate = reader.GetDateTime(8)

    Dim lastActivityDate As DateTime = reader.GetDateTime(9)
    Dim lastPasswordChangedDate As DateTime = reader.GetDateTime(10)

    Dim lastLockedOutDate As DateTime = New DateTime()
    If Not reader.GetValue(11) Is DBNull.Value Then _
      lastLockedOutDate = reader.GetDateTime(11)

    Dim isSubscriber As Boolean = False
    If reader.GetValue(12) IsNot DBNull.Value Then _
      isSubscriber = reader.GetBoolean(12)

    Dim customerID As String = String.Empty
    If reader.GetValue(13) IsNot DBNull.Value Then _
      customerID = reader.GetString(13)

    Dim u As OdbcMembershipUser = New OdbcMembershipUser(Me.Name, _
                                          username, _
                                          providerUserKey, _
                                          email, _
                                          passwordQuestion, _
                                          comment, _
                                          isApproved, _
                                          isLockedOut, _
                                          creationDate, _
                                          lastLoginDate, _
                                          lastActivityDate, _
                                          lastPasswordChangedDate, _
                                          lastLockedOutDate, _
                                          isSubscriber, _
                                          customerID)

    Return u
End Function
//
// MembershipProvider.GetUser(string, bool)
//

public override MembershipUser GetUser(string username, bool userIsOnline)
{
   OdbcConnection conn = new OdbcConnection(connectionString);
   OdbcCommand cmd = new OdbcCommand("SELECT PKID, Username, Email, PasswordQuestion," +
        " Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate," +
        " LastActivityDate, LastPasswordChangedDate, LastLockedOutDate," +
        " IsSubscriber, CustomerID" +
        " FROM Users  WHERE Username = ? AND ApplicationName = ?", conn);

  cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
  cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName;

  OdbcMembershipUser u = null;
  OdbcDataReader reader = null;

  try
  {
    conn.Open();

    reader = cmd.ExecuteReader();

    if (reader.HasRows)
    {
      reader.Read();
      u = GetUserFromReader(reader);

      if (userIsOnline)
      {
        OdbcCommand updateCmd = new OdbcCommand("UPDATE Users  " +
                  "SET LastActivityDate = ? " +
                  "WHERE Username = ? AND Applicationname = ?", conn);

        updateCmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = DateTime.Now;
        updateCmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
        updateCmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName;

        updateCmd.ExecuteNonQuery();
      }
    }

  }
  catch (OdbcException e)
  {
    if (WriteExceptionsToEventLog)
    {
      WriteToEventLog(e, "GetUser(String, Boolean)");

      throw new ProviderException(exceptionMessage);
    }
    else
    {
      throw e;
    }
  }
  finally
  {
    if (reader != null) { reader.Close(); }

    conn.Close();
  }

  return u;      
}


//
// MembershipProvider.GetUser(object, bool)
//

public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
  OdbcConnection conn = new OdbcConnection(connectionString);
  OdbcCommand cmd = new OdbcCommand("SELECT PKID, Username, Email, PasswordQuestion," +
        " Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate," +
        " LastActivityDate, LastPasswordChangedDate, LastLockedOutDate," +
        " IsSubscriber" +
        " FROM Users  WHERE PKID = ?", conn);

  cmd.Parameters.Add("@PKID", OdbcType.UniqueIdentifier).Value = providerUserKey;

  OdbcMembershipUser u = null;
  OdbcDataReader reader = null;

  try
  {
    conn.Open();

    reader = cmd.ExecuteReader();

    if (reader.HasRows)
    {
      reader.Read();
      u = GetUserFromReader(reader);

      if (userIsOnline)
      {
        OdbcCommand updateCmd = new OdbcCommand("UPDATE Users  " +
                  "SET LastActivityDate = ? " +
                  "WHERE PKID = ?", conn);

        updateCmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = DateTime.Now;
        updateCmd.Parameters.Add("@PKID", OdbcType.UniqueIdentifier).Value = providerUserKey;

        updateCmd.ExecuteNonQuery();
      }
    }

  }
  catch (OdbcException e)
  {
    if (WriteExceptionsToEventLog)
    {
      WriteToEventLog(e, "GetUser(Object, Boolean)");

      throw new ProviderException(exceptionMessage);
    }
    else
    {
      throw e;
    }
  }
  finally
  {
    if (reader != null) { reader.Close(); }

    conn.Close();
  }

  return u;      
}


//
// GetUserFromReader
//    A helper function that takes the current row from the OdbcDataReader
// and hydrates a MembershipUser from the values. Called by the 
// MembershipUser.GetUser implementation.
//

private OdbcMembershipUser GetUserFromReader(OdbcDataReader reader)
{
  object providerUserKey = reader.GetValue(0);
  string username = reader.GetString(1);
  string email = reader.GetString(2);

  string passwordQuestion = "";
  if (reader.GetValue(3) != DBNull.Value)
    passwordQuestion = reader.GetString(3);

  string comment = "";
  if (reader.GetValue(4) != DBNull.Value)
    comment = reader.GetString(4);

  bool isApproved = reader.GetBoolean(5);
  bool isLockedOut = reader.GetBoolean(6);
  DateTime creationDate = reader.GetDateTime(7);

  DateTime lastLoginDate = new DateTime();
  if (reader.GetValue(8) != DBNull.Value)
    lastLoginDate = reader.GetDateTime(8);

  DateTime lastActivityDate = reader.GetDateTime(9);
  DateTime lastPasswordChangedDate = reader.GetDateTime(10);

  DateTime lastLockedOutDate = new DateTime();
  if (reader.GetValue(11) != DBNull.Value)
    lastLockedOutDate = reader.GetDateTime(11);

  bool isSubscriber = false;
  if (reader.GetValue(12) != DBNull.Value)
    isSubscriber = reader.GetBoolean(12);

  string customerID = String.Empty;
  if (reader.GetValue(13) != DBNull.Value)
    customerID = reader.GetString(13);        

  OdbcMembershipUser u = new OdbcMembershipUser(this.Name,
                                        username,
                                        providerUserKey,
                                        email,
                                        passwordQuestion,
                                        comment,
                                        isApproved,
                                        isLockedOut,
                                        creationDate,
                                        lastLoginDate,
                                        lastActivityDate,
                                        lastPasswordChangedDate,
                                        lastLockedOutDate,
                                        isSubscriber,
                                        customerID);

  return u;
}

修改 UpdateUser 方法

當使用自訂成員資格使用者型別和自訂成員資格提供者時,會實作將 MembershipUser 型別的物件當做輸入使用的 UpdateUser 方法。在 UpdateUser 方法的實作中,將提供的 MembershipUser 物件轉型為自訂成員資格使用者型別,以便存取其他屬性的值並在資料存放區中將其更新。

下列程式碼範例顯示的是 HOW TO:成員資格提供者實作範例中之成員資格提供者範例修改過的 UpdateUser 方法,其已更新為將提供的使用者轉換為本主題前面建立自訂成員資格使用者一節中所述的自訂成員資格使用者型別。

Public Overrides Sub UpdateUser(ByVal user As MembershipUser)

    Dim conn As OdbcConnection = New OdbcConnection(connectionString)
    Dim cmd As OdbcCommand = New OdbcCommand("UPDATE Users " & _
            " SET Email = ?, Comment = ?," & _
            " IsApproved = ?, IsSubscriber= ?, CustomerID = ?" & _
            " WHERE Username = ? AND ApplicationName = ?", conn)

    Dim u As OdbcMembershipUser = CType(user, OdbcMembershipUser)

    cmd.Parameters.Add("@Email", OdbcType.VarChar, 128).Value = user.Email
    cmd.Parameters.Add("@Comment", OdbcType.VarChar, 255).Value = user.Comment
    cmd.Parameters.Add("@IsApproved", OdbcType.Bit).Value = user.IsApproved
    cmd.Parameters.Add("@IsSubscriber", OdbcType.Bit).Value = u.IsSubscriber
    cmd.Parameters.Add("@CustomerID", OdbcType.VarChar, 128).Value = u.CustomerID
    cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = user.UserName
    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName


    Try
        conn.Open()

        cmd.ExecuteNonQuery()
    Catch e As OdbcException
        If WriteExceptionsToEventLog Then
            WriteToEventLog(e, "UpdateUser")

            Throw New ProviderException(exceptionMessage)
        Else
            Throw e
        End If
    Finally
        conn.Close()
    End Try
End Sub
public override void UpdateUser(MembershipUser user)
{
  OdbcConnection conn = new OdbcConnection(connectionString);
  OdbcCommand cmd = new OdbcCommand("UPDATE Users " +
          " SET Email = ?, Comment = ?," +
          " IsApproved = ?, IsSubscriber = ?, CustomerID = ?" +
          " WHERE Username = ? AND ApplicationName = ?", conn);

  OdbcMembershipUser u = (OdbcMembershipUser)user;

  cmd.Parameters.Add("@Email", OdbcType.VarChar, 128).Value = user.Email;
  cmd.Parameters.Add("@Comment", OdbcType.VarChar, 255).Value = user.Comment;
  cmd.Parameters.Add("@IsApproved", OdbcType.Bit).Value = user.IsApproved;
  cmd.Parameters.Add("@IsSubscriber", OdbcType.Bit).Value = u.IsSubscriber;
  cmd.Parameters.Add("@CustomerID", OdbcType.VarChar, 128).Value = u.CustomerID;
  cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = user.UserName;
  cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName;


  try
  {
    conn.Open();

    cmd.ExecuteNonQuery();
  }
  catch (OdbcException e)
  {
    if (WriteExceptionsToEventLog)
    {
      WriteToEventLog(e, "UpdateUser");

      throw new ProviderException(exceptionMessage);
    }
    else
    {
      throw e;
    }
  }
  finally
  {
    conn.Close();
  }
}

修改 CreateUser 方法

當使用自訂成員資格使用者型別和自訂成員資格提供者時,自訂成員資格提供者必須實作只將 MembershipUser 類別支援的屬性當做輸入使用的 CreateUser 方法。您可以建立使用其他屬性值之 CreateUser 方法的多載,如下列程式碼範例所示。

但是,Membership 類別或依賴 Membership 類別的控制項 (例如 CreateUserWizard 控制項) 將不會呼叫這個多載。若要從應用程式中呼叫這個方法,請將 Membership 類別參考的 MembershipProvider 介面轉型為自訂成員資格提供者型別,然後直接呼叫 CreateUser 多載。

如果您的應用程式是使用 CreateUserWizard 控制項將新使用者加入至成員資格資料來源,則可以自訂 CreateUserWizard 控制項的精靈步驟來包含擷取自訂成員資格使用者之其他屬性值的控制項。之後,您便可以處理 CreateUserWizard 控制項的 CreatedUser 事件,並執行下列各項來加入事件程式碼:

  • 擷取其他成員資格使用者的屬性值。

  • CreateUserWizard 控制項所建立的成員資格使用者轉型為自訂成員資格使用者型別。

  • 設定成員資格使用者上的其他屬性。

  • 將更新的使用者傳遞給 Membership 類別的 UpdateUser 方法。這麼做將會呼叫自訂提供者的 UpdateUser 方法 (如本主題前面修改 UpdateUser 方法一節中所述),將其他屬性值加入至資料來源。

注意事項:

如需修改 CreateUserWizard 的步驟範例,請參閱 HOW TO:自訂 ASP.NET CreateUserWizard 控制項

下列程式碼範例顯示的是 HOW TO:成員資格提供者實作範例中之成員資格提供者範例修改過的 CreateUser 方法,其已更新為傳回本主題前面建立自訂成員資格使用者一節中所述的自訂成員資格使用者型別。當中為了將自訂成員資格提供者的其他屬性值當做輸入使用,已建立了多載。

'
' MembershipProvider.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 MembershipCreateStatus) _
                          As MembershipUser
    Return Me.CreateUser(username, password, email, _
                         passwordQuestion, passwordAnswer, _
                         isApproved, providerUserKey, False, "", status)
End Function


'
' OdbcMembershipProvider.CreateUser -- returns OdbcMembershipUser
'

Public Overloads 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, _
                                     ByVal isSubscriber As Boolean, _
                                     ByVal customerID As String, _
                                     ByRef status As MembershipCreateStatus) _
                          As OdbcMembershipUser

    Dim Args As ValidatePasswordEventArgs = _
      New ValidatePasswordEventArgs(username, password, True)

    OnValidatingPassword(Args)

    If Args.Cancel Then
        status = MembershipCreateStatus.InvalidPassword
        Return Nothing
    End If


    If RequiresUniqueEmail AndAlso GetUserNameByEmail(email) <> "" Then
        status = MembershipCreateStatus.DuplicateEmail
        Return Nothing
    End If

    Dim u As MembershipUser = GetUser(username, False)

    If u Is Nothing Then
        Dim createDate As DateTime = DateTime.Now

        If providerUserKey Is Nothing Then
            providerUserKey = Guid.NewGuid()
        Else
            If Not TypeOf providerUserKey Is Guid Then
                status = MembershipCreateStatus.InvalidProviderUserKey
                Return Nothing
            End If
        End If

        Dim conn As OdbcConnection = New OdbcConnection(connectionString)
        Dim cmd As OdbcCommand = New OdbcCommand("INSERT INTO Users " & _
               " (PKID, Username, Password, Email, PasswordQuestion, " & _
               " PasswordAnswer, IsApproved," & _
               " Comment, CreationDate, LastPasswordChangedDate, LastActivityDate," & _
               " ApplicationName, IsLockedOut, LastLockedOutDate," & _
               " FailedPasswordAttemptCount, FailedPasswordAttemptWindowStart, " & _
               " FailedPasswordAnswerAttemptCount, FailedPasswordAnswerAttemptWindowStart, " & _
               " IsSubscriber, CustomerID)" & _
               " Values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", conn)

        cmd.Parameters.Add("@PKID", OdbcType.UniqueIdentifier).Value = providerUserKey
        cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username
        cmd.Parameters.Add("@Password", OdbcType.VarChar, 255).Value = EncodePassword(password)
        cmd.Parameters.Add("@Email", OdbcType.VarChar, 128).Value = email
        cmd.Parameters.Add("@PasswordQuestion", OdbcType.VarChar, 255).Value = passwordQuestion
        cmd.Parameters.Add("@PasswordAnswer", OdbcType.VarChar, 255).Value = EncodePassword(passwordAnswer)
        cmd.Parameters.Add("@IsApproved", OdbcType.Bit).Value = isApproved
        cmd.Parameters.Add("@Comment", OdbcType.VarChar, 255).Value = ""
        cmd.Parameters.Add("@CreationDate", OdbcType.DateTime).Value = createDate
        cmd.Parameters.Add("@LastPasswordChangedDate", OdbcType.DateTime).Value = createDate
        cmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = createDate
        cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName
        cmd.Parameters.Add("@IsLockedOut", OdbcType.Bit).Value = False
        cmd.Parameters.Add("@LastLockedOutDate", OdbcType.DateTime).Value = createDate
        cmd.Parameters.Add("@FailedPasswordAttemptCount", OdbcType.Int).Value = 0
        cmd.Parameters.Add("@FailedPasswordAttemptWindowStart", OdbcType.DateTime).Value = createDate
        cmd.Parameters.Add("@FailedPasswordAnswerAttemptCount", OdbcType.Int).Value = 0
        cmd.Parameters.Add("@FailedPasswordAnswerAttemptWindowStart", OdbcType.DateTime).Value = createDate
        cmd.Parameters.Add("@IsSubscriber", OdbcType.Bit).Value = isSubscriber
        cmd.Parameters.Add("@CustomerID", OdbcType.VarChar, 128).Value = customerID

        Try
            conn.Open()

            Dim recAdded As Integer = cmd.ExecuteNonQuery()

            If recAdded > 0 Then
                status = MembershipCreateStatus.Success
            Else
                status = MembershipCreateStatus.UserRejected
            End If
        Catch e As OdbcException
            If WriteExceptionsToEventLog Then
                WriteToEventLog(e, "CreateUser")
            End If

            status = MembershipCreateStatus.ProviderError
        Finally
            conn.Close()
        End Try


        Return GetUser(username, False)
    Else
        status = MembershipCreateStatus.DuplicateUserName
    End If

    Return Nothing
End Function
//
// MembershipProvider.CreateUser
//

public override MembershipUser CreateUser(string username,
           string password,
           string email,
           string passwordQuestion,
           string passwordAnswer,
           bool isApproved,
           object providerUserKey,
           out MembershipCreateStatus status)
{
  return this.CreateUser(username, password, email,
                        passwordQuestion, passwordAnswer,
                        isApproved, providerUserKey, false, "",
                        out status);
}


//
// OdbcMembershipProvider.CreateUser -- returns OdbcMembershipUser
//

public OdbcMembershipUser CreateUser(
         string username,
         string password,
         string email,
         string passwordQuestion,
         string passwordAnswer,
         bool isApproved,
         object providerUserKey,
         bool isSubscriber,
         string customerID,
         out MembershipCreateStatus status)
{
  ValidatePasswordEventArgs args = 
    new ValidatePasswordEventArgs(username, password, true);

  OnValidatingPassword(args);

  if (args.Cancel)
  {
    status = MembershipCreateStatus.InvalidPassword;
    return null;
  }

  if (RequiresUniqueEmail && GetUserNameByEmail(email) != "")
  {
    status = MembershipCreateStatus.DuplicateEmail;
    return null;
  }

  MembershipUser u = GetUser(username, false);

  if (u == null)
  {
    DateTime createDate = DateTime.Now;

    if (providerUserKey == null)
    {
      providerUserKey = Guid.NewGuid();
    }
    else
    {
      if ( !(providerUserKey is Guid) )
      {
        status = MembershipCreateStatus.InvalidProviderUserKey;
        return null;
      }
    }

    OdbcConnection conn = new OdbcConnection(connectionString);
    OdbcCommand cmd = new OdbcCommand("INSERT INTO Users " +
          " (PKID, Username, Password, Email, PasswordQuestion, " +
          " PasswordAnswer, IsApproved," +
          " Comment, CreationDate, LastPasswordChangedDate, LastActivityDate," +
          " ApplicationName, IsLockedOut, LastLockedOutDate," +
          " FailedPasswordAttemptCount, FailedPasswordAttemptWindowStart, " +
          " FailedPasswordAnswerAttemptCount, FailedPasswordAnswerAttemptWindowStart, " +
          " IsSubscriber, CustomerID)" +
          " Values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", conn);

    cmd.Parameters.Add("@PKID", OdbcType.UniqueIdentifier).Value = providerUserKey;
    cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username;
    cmd.Parameters.Add("@Password", OdbcType.VarChar, 255).Value = EncodePassword(password);
    cmd.Parameters.Add("@Email", OdbcType.VarChar, 128).Value = email;
    cmd.Parameters.Add("@PasswordQuestion", OdbcType.VarChar, 255).Value = passwordQuestion;
    cmd.Parameters.Add("@PasswordAnswer", OdbcType.VarChar, 255).Value = EncodePassword(passwordAnswer);
    cmd.Parameters.Add("@IsApproved", OdbcType.Bit).Value = isApproved;
    cmd.Parameters.Add("@Comment", OdbcType.VarChar, 255).Value = "";
    cmd.Parameters.Add("@CreationDate", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@LastPasswordChangedDate", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName;
    cmd.Parameters.Add("@IsLockedOut", OdbcType.Bit).Value = false;
    cmd.Parameters.Add("@LastLockedOutDate", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@FailedPasswordAttemptCount", OdbcType.Int).Value = 0;
    cmd.Parameters.Add("@FailedPasswordAttemptWindowStart", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@FailedPasswordAnswerAttemptCount", OdbcType.Int).Value = 0;
    cmd.Parameters.Add("@FailedPasswordAnswerAttemptWindowStart", OdbcType.DateTime).Value = createDate;
    cmd.Parameters.Add("@IsSubscriber", OdbcType.Bit).Value = isSubscriber;
    cmd.Parameters.Add("@CustomerID", OdbcType.VarChar, 128).Value = customerID;

    try
    {
      conn.Open();

      int recAdded = cmd.ExecuteNonQuery();

      if (recAdded > 0)
      {
        status = MembershipCreateStatus.Success;
      }
      else
      {
        status = MembershipCreateStatus.UserRejected;
      }
    }
    catch (OdbcException e)
    {
      if (WriteExceptionsToEventLog)
      {
        WriteToEventLog(e, "CreateUser");
      }

      status = MembershipCreateStatus.ProviderError;
    }
    finally
    {
      conn.Close();
    }


    return (OdbcMembershipUser)GetUser(username, false);      
  }        
  else
  {
    status = MembershipCreateStatus.DuplicateUserName;
  }


  return null;
}

請參閱

概念

實作成員資格提供者

其他資源

使用成員資格管理使用者