6

Das Problem Membership.GetUser funktioniert gut, wenn ich die GUID verwenden, aber nicht, wenn ich es ohne Parameter oder mit dem Namen versuchen:SqlMembershipProvider Membership.GetUser namentlich andernfalls

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

Andere Mysteries

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

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

Das Setup

  • MVC
  • .NET 4.0
  • Standard SQL-Mitgliedschaftsanbieter (keine benutzerdefinierte oder Überschreibungen)

ex:

<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> 
  • Standard-aspnet_ * Datenbanktabellen ohne Anpassung oder zusätzliche Tasten
  • aspnet_Membership_GetAllUsers r wir fine manuell aus der DB. Umgeleitete Ausgabe zeigt, sind die erwarteten Ergebnisse
  • aspnet_Membership_GetUserByName arbeitet auch aus dem
  • DB

Ausnahmedetails

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) 

Gedanken

Es ist fast, als gäbe es etwas falsch zurückgegeben wird in der Membership.GetUser-Methode. Ich dachte den Code für die System.Web.Security.SqlMembershipProvider.GetUser für meine System.Web.dll aus (Version 4.0) und ich folgendes:

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

Nächster Schritt

I‘ Ich hoffe auf eine Richtung von der SO-Crowd auf wo ich als nächstes gehen sollte. Ich denke, ich könnte diese Methode entweder außer Kraft setzen und meinen eigenen Provider zusammenstellen, nur um es zu debuggen, oder ich könnte einfach um das verdammte Ding herumgehen und mich direkt an die DB wenden. Dies scheint eine Menge Herzschmerz von einigen grundlegenden DB CRUD.

Aktuelle Stand

  • 3/5/2013: entdecken ich heute Morgen, dass meine aspnet_Users Tabelle die UserId als nvarchar(256) anstelle ein uniqueidentifier hat. Vielleicht erstickt die SqlDataReader.GetGuid() dort. Ich werde heute Abend ein paar Tests machen, um zu sehen, ob das das Problem ist. Ich frage mich, ob meine Tabellenstruktur veraltet ist, weil Online-Dokumentation dieses Feld als uniqueidentifier zeigt.
+0

Wie schlägt es fehl? Ausnahmedetails bitte. –

+0

Ausnahmedetails hinzugefügt. Die Zeile: System.Data.SqlClient.SqlDataReader.GetGuid (Int32 i) scheint sicher seltsam. – maulkye

+0

Wenn Sie den Code "reflect-out"/reverse-engine/decompile-for-insight ermitteln möchten, sollten Sie sich die Methode GetUser() für die statische Membership-Klasse Membership.GetUser() - it ansehen Dort werden Annahmen über die Identität des aktuellen Benutzers gemacht. GetUser() geht davon aus, dass Details über den CURRENT USER in einer Webanwendung abgerufen werden. –

Antwort

1

Antwort

Mein aspnet_User und aspnet_Membership Tabellen hatte die UserId Satz auf eine Art von nvarchar(256) verwenden.

Discussion

Dies erscheint der Fehler während der folgenden Zeile aus dem SqlMembershipProvider.GetUser Methode ist, daß es:

Guid guid = reader.GetGuid(8); 

I aspnet_regsql.exe aus lief sowohl .NET Frameworks 2 und 4 , und beide setzen die UserId zu einer eindeutigen Kennung, die mich zu der Annahme verleitet, dass ich (immerhin) keine Standard-ASPNET-DB habe.

ein wenig zu graben in der Geschichte des Projekts zeigt, dass diese Mitgliedschaft Datenbank ursprünglich über einen benutzerdefinierten Anbieter für MySql generiert wurde. Ich kann nur schlussfolgern, dass es nie wiederhergestellt wurde, als wir zum Standardanbieter zurück wechselten.

Danke an alle für ihr Feedback.

1

Warum verwenden Sie membership.CurrentUserName()?Sie können nur HttpContext.Current.User.Identity.Name;

Verwandte Themen