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ộtnvarchar(256)
thay vì mộtuniqueidentifier
. 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ộtuniqueidentifier
.
Làm thế nào nó không thành công? Chi tiết ngoại lệ xin vui lòng. –
Đã 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
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 –