Procedura: implementare un utente di appartenenza personalizzato

Aggiornamento: novembre 2007

Viene fornito un esempio in cui viene illustrato come estendere la classe MembershipUser con un provider di appartenenze personalizzato.

Nonostante l'utente System.Web.Profile rappresenti un pratico meccanismo per archiviare informazioni su base utente in un'applicazione Web, la progettazione dell'applicazione potrebbe richiedere l'archiviazione nell'archivio dati Membership delle informazioni aggiuntive e delle informazioni di autenticazione dell'utente. In questo caso, è necessario generare un provider di appartenenze personalizzato per archiviare e recuperare le informazioni di autenticazione dell'utente e i valori aggiuntivi relativi all'utente dall'archivio dati in uso (per un esempio di provider di appartenenze personalizzato, vedere Implementazione di un provider di appartenenze). Inoltre, è possibile estendere la classe MembershipUser affinché i valori aggiuntivi dell'utente siano disponibili nel codice dell'applicazione.

Per creare un utente di appartenenza personalizzato è necessario eseguire le attività seguenti:

  • Creare una classe che erediti dalla classe MembershipUser.

  • Creare un'origine dati per archiviare informazioni di autenticazione e impostazioni utente aggiuntive.

  • Creare un provider di appartenenze personalizzato per l'archivio dati. Tale provider contiene codice aggiuntivo che può ricevere come input oggetti del tipo utente di appartenenza personalizzato, nonché restituire oggetti del tipo utente di appartenenza personalizzato.

Negli esempi di questo argomento viene illustrato come modificare l'esempio del provider di appartenenze personalizzato in Procedura: implementazione di un provider di appartenenze di esempio per supportare un'implementazione di utente di appartenenza personalizzato.

Creazione di un utente di appartenenza personalizzato

È possibile creare un utente di appartenenza personalizzato creando una classe che eredita la classe MembershipUser e quindi includere le proprietà che espongono i valori utente aggiuntivi. Facoltativamente, è anche possibile aggiungere metodi ed eventi alla classe MembershipUser.

Quando la classe Membership viene chiamata per creare un'istanza della classe personalizzata MembershipUser, verranno chiamati solo i costruttori definiti dalla classe MembershipUser. Se l'implementazione MembershipUser include overload del costruttore aggiuntivi, tali costruttori verranno chiamati solo da codice dell'applicazione scritto appositamente per chiamare un costruttore personalizzato.

Nell'esempio di codice seguente viene illustrato un semplice utente di appartenenza personalizzato che eredita la classe MembershipUser e fornisce due proprietà aggiuntive: IsSubscriber, che è una proprietà Boolean che identifica se l'utente sottoscrive un servizio o un notiziario per un'applicazione Web e CustomerID, che contiene un identificatore univoco per un database clienti distinto.

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;
        }



    }
}

Per un esempio di modifica del controllo CreateUserWizard per includere informazioni utente aggiuntive per un utente di appartenenza, vedere Procedura: personalizzare il controllo CreateUserWizard ASP.NET.

Creazione di un archivio dati per i dati dell'utente di appartenenza

È necessario fornire un archivio dati per le informazioni di autenticazione utente per la funzionalità di appartenenza, nonché per le informazioni utente aggiuntive dell'utente di appartenenza personalizzato.

Nell'esempio di codice seguente viene illustrata una query che è possibile eseguire in un database Microsoft Access per creare una tabella in cui archiviare informazioni di autenticazione e valori di proprietà per l'utente di appartenenza personalizzato.

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)
)

Creazione di un provider di appartenenze personalizzato

È necessario creare un provider di appartenenze personalizzato che supporta sia il tipo utente di appartenenza personalizzato sia l'archivio dati di appartenenze personalizzato. È possibile scrivere i metodi GetUser e CreateUser del provider di appartenenze personalizzato per restituire oggetti del tipo utente di appartenenza personalizzato. È possibile scrivere il metodo UpdateUser del provider di appartenenze personalizzato per ricevere come input un oggetto del tipo utente di appartenenza personalizzato.

Nelle sezioni seguenti vengono fornite linee guida per la creazione di un provider di appartenenze personalizzato che utilizza un tipo utente di appartenenza personalizzato. Gli esempi si basano sul codice fornito in Procedura: implementazione di un provider di appartenenze di esempio e utilizzano lo schema del database della sezione Creazione di un archivio dati per i dati dell'utente di appartenenza più indietro in questo argomento.

Modifica dei metodi GetUser

Quando si utilizza un tipo utente di appartenenza personalizzato, i metodi MembershipProvider.GetUser e MembershipProvider.GetUser del provider di appartenenze in uso devono restituire un oggetto di tipo MembershipUser. A condizione che la classe dell'utente di appartenenza personalizzato erediti la classe MembershipUser, restituire un oggetto del tipo utente di appartenenza personalizzato come valore restituito per l'implementazione dei metodi GetUser. Il codice dell'applicazione può quindi eseguire il cast dell'oggetto MembershipUser restituito come tipo utente di appartenenza personalizzato per accedere ai membri aggiuntivi dell'utente di appartenenza personalizzato, come illustrato nell'esempio di codice seguente.

Nell'esempio di codice seguente vengono illustrati i metodi GetUser modificati (e il relativo metodo privato di supporto) del provider di appartenenze di esempio di Procedura: implementazione di un provider di appartenenze di esempio. Tali metodi sono stati aggiornati per restituire il tipo utente di appartenenza personalizzato della sezione Creazione di un utente di appartenenza personalizzato più indietro in questo argomento.

'
' 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;
}

Modifica del metodo UpdateUser

Quando si utilizza un tipo utente di appartenenza personalizzato e un provider di appartenenze personalizzato, implementare un metodo UpdateUser che accetta come input un oggetto di tipo MembershipUser. Nell'implementazione del metodo UpdateUser, eseguire il cast dell'oggetto MembershipUser fornito come tipo utente di appartenenza personalizzato per accedere ai valori delle proprietà aggiuntive e aggiornarli nell'archivio dati.

Nell'esempio di codice seguente viene illustrato il metodo UpdateUser modificato del provider di appartenenze di esempio di Procedura: implementazione di un provider di appartenenze di esempio. Tale metodo è stato aggiornato per eseguire il cast dell'utente fornito come tipo utente di appartenenza personalizzato della sezione Creazione di un utente di appartenenza personalizzato più indietro in questo argomento.

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();
  }
}

Modifica del metodo CreateUser

Quando si utilizza un tipo utente di appartenenza personalizzato e un provider di appartenenze personalizzato, il provider deve implementare un metodo CreateUser che accetta come input solo le proprietà supportate dalla classe MembershipUser. È possibile creare un overload del metodo CreateUser che accetta valori delle proprietà aggiuntive, come illustrato nell'esempio di codice seguente.

Tuttavia, questo overload non verrà chiamato dalla classe Membership o da controlli che si basano sulla classe Membership, ad esempio il controllo CreateUserWizard. Per chiamare questo metodo da un'applicazione, eseguire il cast dell'istanza MembershipProvider a cui viene fatto riferimento dalla classe Membership come tipo di provider di appartenenze personalizzato e quindi chiamare direttamente l'overload CreateUser.

Se l'applicazione utilizza il controllo CreateUserWizard per aggiungere utenti nuovi all'origine dati delle appartenenze, è possibile personalizzare i passaggi della procedura guidata del controllo CreateUserWizard per includere controlli che recuperano i valori delle proprietà aggiuntive per l'utente di appartenenza personalizzato. È quindi possibile gestire l'evento CreatedUser del controllo CreateUserWizard e aggiungere codice dell'evento che esegue le operazioni seguenti:

  • Recupero dei valori delle proprietà dell'utente di appartenenza aggiuntivo.

  • Esecuzione del cast dell'utente di appartenenza creato dal controllo CreateUserWizard come tipo utente di appartenenza personalizzato.

  • Impostazione delle proprietà aggiuntive nell'utente di appartenenza.

  • Passaggio dell'utente aggiornato al metodo UpdateUser della classe Membership. In questo modo verrà chiamato il metodo UpdateUser del provider personalizzato (illustrato nella sezione Modifica del metodo UpdateUser più indietro in questo argomento) per aggiungere i valori delle proprietà aggiuntive all'origine dati.

Nota:

Per un esempio di modifica dei passaggi della CreateUserWizard, vedere Procedura: personalizzare il controllo CreateUserWizard ASP.NET.

Nell'esempio di codice seguente viene illustrato il metodo CreateUser modificato del provider di appartenenze di esempio di Procedura: implementazione di un provider di appartenenze di esempio. Tale metodo è stato aggiornato per restituire il tipo utente di appartenenza personalizzato della sezione Creazione di un utente di appartenenza personalizzato più indietro in questo argomento. È stato creato un overload che accetta come input valori per le proprietà aggiuntive del provider di appartenenze personalizzato.

'
' 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;
}

Vedere anche

Concetti

Implementazione di un provider di appartenenze

Altre risorse

Gestione di utenti tramite l'appartenenza