2012-06-14 3 views
1

Sur mon CreateUserWizard, j'invoquer des propriétés supplémentaires et quand je l'appelle GetUser(), je reçois:

« Il existe déjà un DataReader ouverte associée à cette commande qui doit d'abord être fermé »

Le codebehind de Registration.aspx:La bonne façon d'appeler les méthodes MembershipProvider?

 NCCMembershipUser currentUser = (NCCMembershipUser)Membership.GetUser(); 
     Guid id = (Guid)currentUser.ProviderUserKey; 

     ...assigning control values to membership values... 

     try 
     { 
      NCCMembershipProvider u = (NCCMembershipProvider)Membership.Provider; 
      u.UpdateUser(currentUser); 
     } 

Est-ce que je ne devrais pas utiliser GetUser pour accéder aux propriétés?

est ici la méthode GetUser:

public override MembershipUser GetUser(string username, bool userIsOnline) 
    { 
     SqlConnection conn = new SqlConnection(connectionString); 
     SqlCommand cmd = new SqlCommand("SELECT UserID," + 
      " Email," + 
      " Comment," + 
      " PasswordQuestion," + 
      " IsApproved," + 
      " LastActivityDate," + 
      " LastLoginDate," + 
      " LastPasswordChangedDate," + 
      " CreationDate," + 
      " IsLockedOut," + 
      " LastLockedOutDate," + 
      " UserSalutation," + 
      " UserFirstName," + 
      " UserLastName," + 
      " UserPosition," + 
      " UserCompany," + 
      " UserCompanyType," + 
      " UserCompanyTypeOther," + 
      " UserAccountType," + 
      " UserAddress1," + 
      " UserAddress2," + 
      " UserCity," + 
      " UserStateProv," + 
      " UserPostal," + 
      " UserCountry," + 
      " UserWebsite," + 
      " UserPhone," + 
      " UserPhoneExt," + 
      " UserFax," + 
      " UserIP," + 
      " UserIPLastLogin," + 
      " IsSubscribed," + 
      " LikeAreaRugs," + 
      " LikeCarpeting," + 
      " LikeCoverings," + 
      " LikeComponents," + 
      " LikeHotel," + 
      " LikeAccessories" + 
      " FROM Users WHERE Email = @Email AND ApplicationName = @ApplicationName", conn); 

     cmd.Parameters.Add("@Email", SqlDbType.NVarChar, 128).Value = username; 
     cmd.Parameters.Add("@ApplicationName", SqlDbType.NVarChar, 255).Value = m_ApplicationName; 

     NCCMembershipUser u = null; 
     SqlDataReader reader = null; 

     try 
     { 
      conn.Open(); 

      reader = cmd.ExecuteReader(); 

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

       if (userIsOnline) 
       { 
        SqlCommand updateCmd = new SqlCommand("UPDATE Users " + 
         "SET LastActivityDate = @LastActivityDate " + 
         "WHERE Email = @Email AND ApplicationName = @ApplicationName", conn); 

        updateCmd.Parameters.Add("@LastActivityDate", SqlDbType.DateTime).Value = DateTime.Now; 
        updateCmd.Parameters.Add("@Email", SqlDbType.VarChar, 255).Value = username; 
        updateCmd.Parameters.Add("@ApplicationName", SqlDbType.VarChar, 255).Value = m_ApplicationName; 

        updateCmd.ExecuteNonQuery();//<<------Error:"There is already an open DataReader associated with this Command which must be closed first." 
       } 
      } 

     } 
     catch (SqlException 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; 
    } 
+0

Il n'y a aucune raison pour laquelle vous ne pouvez pas appeler les membres de l'adhésion à volonté. Cela me semble être un bug avec ce que 'NCCMembershipProvider' est. – HackedByChinese

+0

J'ai un fournisseur d'appartenances personnalisées distinct, mais le code est directement hors de MSDN. Je vais publier la méthode GetUser maintenant. – RyanJMcGowan

Répondre

2

Vous devez Close le lecteur avant d'émettre la déclaration de mise à jour.

try 
    { 
     conn.Open(); 

     reader = cmd.ExecuteReader(); 

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

      reader.Close(); 

      if (userIsOnline) 
      { 
       SqlCommand updateCmd = new SqlCommand("UPDATE Users " + 
        "SET LastActivityDate = @LastActivityDate " + 
        "WHERE Email = @Email AND ApplicationName = @ApplicationName", conn); 

       updateCmd.Parameters.Add("@LastActivityDate", SqlDbType.DateTime).Value = DateTime.Now; 
       updateCmd.Parameters.Add("@Email", SqlDbType.VarChar, 255).Value = username; 
       updateCmd.Parameters.Add("@ApplicationName", SqlDbType.VarChar, 255).Value = m_ApplicationName; 

       updateCmd.ExecuteNonQuery(); 
      } 
     } 
     else 
     { 
      reader.Close() 
     } 

    } 
+0

Cela a certainement aidé. Ça ne me donne plus cette erreur. Mais je reçois _InvalidCastException_ sur la ligne 'NCCMembershipUser u = (NCCMembershipUser) Membership.GetUser();' après avoir fini de passer par la méthode. Je suis nouveau sur .NET et C#, mais quelque chose ne semble pas logique sur la façon dont il communique avec le fournisseur d'adhésion. Je veux simplement afficher mes valeurs dans la ligne de base de données de l'utilisateur actuel. Suis-je sur la bonne voie? – RyanJMcGowan

+0

@RyanJMcGowan Vérifiez le type retourné par 'Membership.GetUser();' sans le lancer pour confirmer le problème. C'est la manière standard d'utiliser l'API du fournisseur d'appartenance. Avec un peu de débogage, vous pourrez trouver le problème. – Eranga

+0

J'essaye d'envelopper ma tête autour de ceci. 'GetUser' renvoie un' MembershipUser'. Je crois que le problème est que 'MembershipUser' a moins de paramètres que mon 'NCCMembershipProvider' personnalisé donc il ne lance pas. J'ai deux surcharges de remplacement pour GetUser: 'GetUser (chaîne de nom d'utilisateur, bool userIsOnline)' et 'GetUser (objet providerUserKey, bool userIsOnline)', mais je dois utiliser 'GetUser()' pour retourner l'utilisateur actuellement connecté. Il semble que 'GetUser()' ne peut pas être remplacé. Donc 'membership.GetUser()' ne peut pas référencer complètement 'NCCMembershipUser'. – RyanJMcGowan

Questions connexes