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 laUserId
comenvarchar(256)
invece di ununiqueidentifier
. Forse ilSqlDataReader.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 comeuniqueidentifier
.
Come fallisce? Dettagli di eccezione per favore. –
Aggiunti dettagli di eccezione. La linea: System.Data.SqlClient.SqlDataReader.GetGuid (Int32 i) sembra sicuro. – maulkye
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 –