6

Il problema Membership.GetUser funziona bene se uso il GUID, ma non riesce se provo senza parametri o con il nome:SqlMembershipProvider Membership.GetUser per nome non avendo

//This works and adds records to aspnet_user & aspnet_Membership tables 
MembershipUser membershipUser = Membership.CreateUser(_name, _pwd, _email, null, null, true, null, out createStatus); 

//These fail with an InvalidCastException 
MembershipUser membershipUser2 = Membership.GetUser(_name, true); 
MembershipUser membershipUser3 = Membership.GetUser(); 

//If I go look up the GUID for this user (userId), this works! 
MembershipUser membershipUser4 = Membership.GetUser(new Guid("E1428CD3-CF17-494E-AB77-CF8F6010F585"), true); 

altri misteri

//This works 
Int32 count = Membership.GetNumberOfUsersOnline();  

//this fails (but totalRecords has the right value) 
Int32 totalRecords; 
MembershipUserCollection col = Membership.GetAllUsers(0,100, out totalRecords); 

L'installazione

  • MVC
  • .NET 4.0
  • predefinito SQL provider di appartenenze (non personalizzato o le sostituzioni)

es:

<membership defaultProvider="SqlProvider"> 
    <providers> 
     <clear /> 
     <add name="SqlProvider" 
      type="System.Web.Security.SqlMembershipProvider" 
      connectionStringName="MyDB" 
      enablePasswordRetrieval="false" 
      enablePasswordReset="true" 
      requiresQuestionAndAnswer="false" 
      applicationName="myapp" 
      requiresUniqueEmail="false" 
      passwordFormat="Hashed" 
      maxInvalidPasswordAttempts="5" 
      minRequiredPasswordLength="2" 
      minRequiredNonalphanumericCharacters="0" 
      passwordAttemptWindow="10" 
      passwordStrengthRegularExpression="" /> 
    </providers> 
</membership> 
  • aspnet_ standard * tabelle del database senza la personalizzazione o chiavi extra
  • aspnet_Membership_GetAllUsers r uns fine manualmente dal DB. Uscita reindirizzate mostra i risultati attesi vengono restituiti
  • aspnet_Membership_GetUserByName sta lavorando come pure dal DB

Dettagli eccezione

Specified cast is not valid. 
    at System.Data.SqlClient.SqlBuffer.get_SqlGuid() 
    at System.Data.SqlClient.SqlDataReader.GetGuid(Int32 i) 
    at System.Web.Security.SqlMembershipProvider.GetUser(String username, Boolean userIsOnline) 
    at System.Web.Security.Membership.GetUser(String username, Boolean userIsOnline) 

Pensieri

E 'quasi come se ci fosse qualcosa di sbagliato all'interno del metodo Membership.GetUser. Ho riflettuto fuori il codice per lo System.Web.Security.SqlMembershipProvider.GetUser per la mia System.Web.dll (versione 4.0) e ottengo il seguente:

public override MembershipUser GetUser(string username, bool userIsOnline) 
{ 
    SecUtility.CheckParameter(ref username, true, false, true, 256, "username"); 
    SqlDataReader reader = (SqlDataReader) null; 
    try 
    { 
    SqlConnectionHolder connectionHolder = (SqlConnectionHolder) null; 
    try 
    { 
     connectionHolder = SqlConnectionHelper.GetConnection(this._sqlConnectionString, true); 
     this.CheckSchemaVersion(connectionHolder.Connection); 
     SqlCommand sqlCommand = new SqlCommand("dbo.aspnet_Membership_GetUserByName", connectionHolder.Connection); 
     sqlCommand.CommandTimeout = this.CommandTimeout; 
     sqlCommand.CommandType = CommandType.StoredProcedure; 
     sqlCommand.Parameters.Add(this.CreateInputParam("@ApplicationName", SqlDbType.NVarChar, (object) this.ApplicationName)); 
     sqlCommand.Parameters.Add(this.CreateInputParam("@UserName", SqlDbType.NVarChar, (object) username)); 
     sqlCommand.Parameters.Add(this.CreateInputParam("@UpdateLastActivity", SqlDbType.Bit, (object) (bool) (userIsOnline ? 1 : 0))); 
     sqlCommand.Parameters.Add(this.CreateInputParam("@CurrentTimeUtc", SqlDbType.DateTime, (object) DateTime.UtcNow)); 
     SqlParameter sqlParameter = new SqlParameter("@ReturnValue", SqlDbType.Int); 
     sqlParameter.Direction = ParameterDirection.ReturnValue; 
     sqlCommand.Parameters.Add(sqlParameter); 
     reader = sqlCommand.ExecuteReader(); 
     if (!reader.Read()) 
     return (MembershipUser) null; 
     string nullableString1 = this.GetNullableString(reader, 0); 
     string nullableString2 = this.GetNullableString(reader, 1); 
     string nullableString3 = this.GetNullableString(reader, 2); 
     bool boolean1 = reader.GetBoolean(3); 
     DateTime creationDate = reader.GetDateTime(4).ToLocalTime(); 
     DateTime lastLoginDate = reader.GetDateTime(5).ToLocalTime(); 
     DateTime lastActivityDate = reader.GetDateTime(6).ToLocalTime(); 
     DateTime lastPasswordChangedDate = reader.GetDateTime(7).ToLocalTime(); 
     Guid guid = reader.GetGuid(8); 
     bool boolean2 = reader.GetBoolean(9); 
     DateTime lastLockoutDate = reader.GetDateTime(10).ToLocalTime(); 
     return new MembershipUser(this.Name, username, (object) guid, nullableString1, nullableString2, nullableString3, boolean1, boolean2, creationDate, lastLoginDate, lastActivityDate, lastPasswordChangedDate, lastLockoutDate); 
    } 
    finally 
    { 
     if (reader != null) 
     reader.Close(); 
     if (connectionHolder != null) 
     connectionHolder.Close(); 
    } 
    } 
    catch 
    { 
    throw; 
    } 
} 

prossimo passo

I' spero di ottenere una direzione dalla folla SO su dove dovrei andare dopo. Immagino di poter ignorare questo metodo e mettere insieme il mio provider solo per eseguire il debug, o potrei semplicemente aggirare la cosa dannata e chiamare direttamente il DB direttamente. Questo sembra un sacco di angoscia da alcuni DB CRUD di base.

Stato corrente

  • 3/5/2013: ho scoperto questa mattina che la mia tabella aspnet_Users ha la UserId come nvarchar(256) invece di un uniqueidentifier. Forse il SqlDataReader.GetGuid() sta soffocando lì. Questa sera farò dei test per vedere se questo è il problema. Mi chiedo se la struttura della mia tabella non sia aggiornata, perché la documentazione online mostra questo campo come uniqueidentifier.
+0

Come fallisce? Dettagli di eccezione per favore. –

+0

Aggiunti dettagli di eccezione. La linea: System.Data.SqlClient.SqlDataReader.GetGuid (Int32 i) sembra sicuro. – maulkye

+0

Inoltre, se si intende "reflect-out"/reverse-engineer/decompile-for-insight del codice, si dovrebbe prendere in considerazione il metodo GetUser() nella classe Membership statica - Membership.GetUser() - it È lì dove vengono fatte ipotesi sull'identità dell'utente corrente. GetUser() presuppone che stia recuperando dettagli sull'UTENTE CORRENTE in un'applicazione web –

risposta

1

risposte

mio aspnet_User e aspnet_Membership tavoli avevano la UserId insieme ad un tipo di nvarchar(256).

Discussione

Questo sembra essere causa l'errore durante la seguente riga dal metodo SqlMembershipProvider.GetUser:

Guid guid = reader.GetGuid(8); 

Ho eseguito aspnet_regsql.exe da entrambi NET framework 2 e 4 e entrambi impostano l'ID utente su un identificatore univoco, inducendomi a pensare che non avessi (dopotutto) un DB ASPNET standard.

Un po 'di scavo nella storia del progetto rivela che questo database di appartenenza è stato originariamente generato tramite un provider personalizzato per MySql. Posso solo concludere che non è mai stato rigenerato quando siamo tornati al provider predefinito.

Grazie a tutti per il loro feedback.

1

Perché si utilizza membership.CurrentUserName()?Si può semplicemente utilizzare HttpContext.Current.User.Identity.Name;