6

Vấn đề Membership.GetUser hoạt động tốt nếu tôi sử dụng GUID, nhưng thất bại nếu tôi cố gắng nó không có tham số hoặc với tên:SqlMembershipProvider Membership.GetUser theo tên không

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

Mysteries khác

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

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

Setup

  • MVC
  • .NET 4.0
  • Mặc định Membership SQL Provider (không tùy chỉnh hoặc ghi đè)

ví dụ:

<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_ Chuẩn * bảng cơ sở dữ liệu với không chỉnh hoặc các phím bổ sung
  • aspnet_Membership_GetAllUsers r không tốt bằng tay từ DB. đầu ra chuyển hướng cho thấy các kết quả mong đợi đang được trả lại
  • aspnet_Membership_GetUserByName đang làm việc cũng từ DB

Ngoại lệ chi tiết

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) 

Suy nghĩ

Nó gần giống như có điều gì đó sai bên trong phương thức Membership.GetUser. Tôi phản ánh ra mã cho System.Web.Security.SqlMembershipProvider.GetUser cho System.Web.dll tôi (phiên bản 4.0) và tôi nhận được như sau:

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

Tiếp Bước

tôi m hy vọng sẽ nhận được một số hướng từ SO đám đông về nơi tôi nên đi tiếp theo. Tôi hình dung rằng tôi có thể ghi đè phương pháp này và cùng nhau đưa nhà cung cấp của riêng mình vào để gỡ lỗi, hoặc tôi có thể đi vòng quanh điều darned và gọi trực tiếp cho DB. Điều này có vẻ như rất nhiều đau khổ từ một số DB CRUD cơ bản.

Trạng thái hiện

  • 3/5/2013: Tôi phát hiện sáng nay rằng bảng aspnet_Users tôi có UserId như một nvarchar(256) thay vì một uniqueidentifier. Có lẽ SqlDataReader.GetGuid() đang bị nghẹt thở ở đó. Tôi sẽ chạy một số bài kiểm tra tối nay để xem đó có phải là vấn đề không. Tôi tự hỏi nếu cấu trúc bảng của tôi là lỗi thời, bởi vì tài liệu trực tuyến cho thấy lĩnh vực này như là một uniqueidentifier.
+0

Làm thế nào nó không thành công? Chi tiết ngoại lệ xin vui lòng. –

+0

Đã thêm chi tiết ngoại lệ. Dòng: System.Data.SqlClient.SqlDataReader.GetGuid (Int32 i) chắc chắn có vẻ lạ. – maulkye

+0

Ngoài ra, nếu bạn sẽ "phản ánh"/đảo ngược/kỹ thuật/giải mã-cho-cái nhìn sâu sắc mã, bạn nên nhìn vào phương pháp GetUser() trên lớp thành viên tĩnh - Membership.GetUser() - nó là nơi mà các giả định đang được thực hiện về danh tính của người dùng hiện tại. GetUser() giả định rằng nó đang lấy thông tin chi tiết về CURRENT USER trong một ứng dụng web –

Trả lời

1

trả lời

My aspnet_User và aspnet_Membership bảng có UserId thiết lập để một loại nvarchar(256).

Thảo luận

này dường như đã được gây ra lỗi trong dòng sau từ phương pháp SqlMembershipProvider.GetUser:

Guid guid = reader.GetGuid(8); 

Tôi chạy aspnet_regsql.exe từ cả hai khuôn khổ NET 2 và 4 , và cả hai thiết lập UserId để một uniqueidentifier, dẫn tôi nghĩ rằng tôi đã không (sau khi tất cả) có một tiêu chuẩn ASPNET DB.

Một đào ít nhất trong lịch sử của dự án cho thấy rằng cơ sở dữ liệu thành viên này ban đầu được tạo ra thông qua một nhà cung cấp tùy chỉnh cho MySql. Tôi chỉ có thể kết luận rằng nó không bao giờ được tái sinh khi chúng tôi chuyển về nhà cung cấp mặc định.

Cảm ơn mọi người vì phản hồi của họ.

1

Tại sao bạn sử dụng membership.CurrentUserName()?Bạn chỉ có thể sử dụng HttpContext.Current.User.Identity.Name;

Các vấn đề liên quan