6

Проблема Membership.GetUser отлично работает, если я использую GUID, но терпит неудачу, если я попробовать его без параметров или с именем:SqlMembershipProvider Membership.GetUser по имени неисправного

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

Другие Тайн

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

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

установки параметров

  • MVC
  • .NET 4.0
  • По умолчанию SQL Membership Provider (нет пользовательских или переопределение)

например:

<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_ * таблицы базы данных без каких-либо настройки или дополнительные ключи
  • aspnet_Membership_GetAllUsers r нечетко вручную из БД. Redirected выход показывает ожидаемые результаты возвращаются
  • aspnet_Membership_GetUserByName работает, а из БД

Exception Детали

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) 

Мысли

Это почти как-то не так внутри метода Membership.GetUser. Я размышлял из кода для System.Web.Security.SqlMembershipProvider.GetUser для моего System.Web.dll (версия 4.0), и я получаю следующее:

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

Следующий шаг

Я м надеясь получить какое-то направление от толпы SO, где я должен идти дальше. Я полагаю, что могу либо переопределить этот метод, либо собрать своего собственного поставщика, чтобы отлаживать его, или я мог бы просто обойти проклятую вещь и напрямую обратиться к БД. Это похоже на большую страдания от базового DB CRUD.

Текущий статус

  • 3/5/2013: Я обнаружил сегодня утром, что мой aspnet_Users таблица имеет UserId как nvarchar(256) вместо uniqueidentifier. Возможно, SqlDataReader.GetGuid() задыхается. Сегодня вечером я проведу несколько тестов, чтобы понять, не проблема. Мне интересно, устарела ли моя структура таблицы, потому что онлайн-документация показывает это поле как uniqueidentifier.
+0

Как это происходит? Исключить. –

+0

Добавлены сведения об исключениях. Строка: System.Data.SqlClient.SqlDataReader.GetGuid (Int32 i) кажется странной. – maulkye

+0

Кроме того, если вы собираетесь «задуматься»/обратный инженер/декомпилировать для понимания кода, вы должны посмотреть на метод GetUser() на статическом классе членства - Membership.GetUser() - it есть ТАК, где делаются предположения о личности текущего пользователя. GetUser() предполагает, что он получает подробную информацию о CURRENT USER в веб-приложении –

ответ

1

Ответ

Мои aspnet_User и aspnet_Membership столы имели UserId набор к типу nvarchar(256).

Обсуждение

Это, кажется, был причиной ошибки при следующей строки из метода SqlMembershipProvider.GetUser:

Guid guid = reader.GetGuid(8); 

Я побежал aspnet_regsql.exe с обеих .NET рамок 2 и 4 , и оба устанавливают UserId в uniqueidentifier, что приводит меня к мысли, что я не (в конце концов) имел стандартную базу данных ASPNET.

немного покопаться в истории проекта показывает, что эта база данных членства была первоначально генерируется через настраиваемого поставщика для MySql. Я могу только сделать вывод, что он никогда не восстанавливался, когда мы возвращались к поставщику по умолчанию.

Спасибо всем за отзыв.

1

Почему вы используете membership.CurrentUserName()?Вы можете просто использовать HttpContext.Current.User.Identity.Name;