tôi thực hiện một đối tượng tùy chỉnh hồ sơ trong mã như mô tả của Joel đây:Sử dụng ASP .NET Membership và Profile với MVC, làm thế nào tôi có thể tạo một người dùng và đặt nó thành HttpContext.Current.User?
tôi không thể làm cho nó hoạt động khi tôi đang tạo một người dùng mới, tuy nhiên. Khi tôi làm điều này:
Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyRole");
người dùng được tạo ra và thêm vào một vai trò trong cơ sở dữ liệu, nhưng HttpContext.Current.User
vẫn còn trống rỗng, và Membership.GetUser()
lợi nhuận null, vì vậy đây (từ mã của Joel) không hoạt động:
static public AccountProfile CurrentUser
{
get { return (AccountProfile)
(ProfileBase.Create(Membership.GetUser().UserName)); }
}
AccountProfile.CurrentUser.FullName = "Snoopy";
tôi đã thử gọi Membership.GetUser(userName)
và thiết lập các thuộc hồ sơ như vậy, nhưng các thuộc tính thiết lập vẫn trống rỗng, và kêu gọi AccountProfile.CurrentUser(userName).Save()
không đặt bất cứ điều gì trong cơ sở dữ liệu. Tôi cũng đã cố gắng cho biết rằng người dùng đã đăng nhập & hợp lệ, bằng cách gọi Membership.ValidateUser
, FormsAuthentication.SetAuthCookie
, v.v. nhưng người dùng hiện tại vẫn không có hoặc ẩn danh (tùy thuộc vào trạng thái cookie của trình duyệt của tôi).
GIẢI PHÁP (CHỈNH SỬA THÊM, XEM DƯỚI): Dựa trên lời giải thích của Franci Penov và một số thử nghiệm khác, tôi đã tìm ra vấn đề. Mã của Joel và các biến thể mà tôi đã thử sẽ chỉ hoạt động với Cấu hình hiện có. Nếu không có Tiểu sử nào tồn tại, ProfileBase.Create(userName)
sẽ trả về một đối tượng trống mới mỗi khi được gọi; bạn có thể thiết lập các thuộc tính, nhưng chúng sẽ không "dính" vì một cá thể mới được trả về mỗi lần bạn truy cập nó. Đặt HttpContext.Current.User
thành GenericPrincipal
mới sẽ cung cấp cho bạn đối tượng Người dùng, nhưng không đối tượng Tiểu sử và ProfileBase.Create(userName)
và HttpContext.Current.Profile
sẽ vẫn trỏ đến đối tượng mới, trống.
Nếu bạn muốn tạo Hồ sơ cho Người dùng mới được tạo trong cùng một yêu cầu, bạn cần gọi HttpContext.Current.Profile.Initialize(userName, true)
. Sau đó, bạn có thể điền tiểu sử được khởi tạo và lưu nó, và nó sẽ có thể truy cập được trên các yêu cầu trong tương lai theo tên, do đó mã của Joel sẽ hoạt động. Tôi chỉ chỉ sử dụng HttpContext.Current.Profile
nội bộ, khi tôi cần tạo/truy cập vào Tiểu sử ngay khi tạo. Trên bất kỳ yêu cầu nào khác, tôi sử dụng ProfileBase.Create(userName)
và tôi đã chỉ hiển thị phiên bản đó là công khai. Lưu ý rằng Franci là chính xác: Nếu bạn sẵn sàng tạo User (và Vai trò) và đặt nó là Authenticated trên chuyến đi khứ hồi đầu tiên, và yêu cầu người dùng đăng nhập, bạn sẽ có thể truy cập vào Hồ sơ nhiều hơn nữa chỉ đơn giản là thông qua mã của Joel về yêu cầu tiếp theo. Điều gì đã ném tôi là Roles có thể truy cập ngay lập tức khi người dùng tạo mà không có bất kỳ khởi tạo nào, nhưng Hồ sơ thì không.
đang AccountProfile mới của tôi:
public static AccountProfile CurrentUser
{
get
{
if (Membership.GetUser() != null)
return ProfileBase.Create(Membership.GetUser().UserName) as AccountProfile;
else
return null;
}
}
internal static AccountProfile NewUser
{
get { return System.Web.HttpContext.Current.Profile as AccountProfile; }
}
tạo người dùng mới:
MembershipUser user = Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyBasicUserRole");
AccountProfile.NewUser.Initialize(userName, true);
AccountProfile.NewUser.FullName = "Snoopy";
AccountProfile.NewUser.Save();
truy cập tiếp theo:
if (Membership.ValidateUser(userName, password))
{
string name = AccountProfile.CurrentUser.FullName;
}
nhờ Hơn nữa để Franci cho giải thích vòng đời xác thực - Tôi m gọi FormsAuthentication.SetAuthCookie trong chức năng xác nhận của tôi, nhưng tôi trả lại một bo ol để cho biết thành công, vì User.Identity.IsAuthenticated sẽ không đúng cho đến khi yêu cầu tiếp theo.
ĐƯỢC SỬA ĐỔI: Tôi là kẻ ngốc. Lời giải thích ở trên hoạt động trong trường hợp hẹp, nhưng không giải quyết được vấn đề cốt lõi: Gọi CurrentUser trả về một cá thể mới của đối tượng mỗi lần, cho dù đó là một Profile hiện có hay không. Bởi vì nó được định nghĩa là một tài sản, tôi đã không nghĩ về điều này, và đã viết:
AccountProfile.CurrentUser.FullName = "Snoopy";
AccountProfile.CurrentUser.OtherProperty = "ABC";
AccountProfile.CurrentUser.Save();
mà (tất nhiên) không hoạt động. Nó phải là:
AccountProfile currentProfile = AccountProfile.CurrentUser;
currentProfile.FullName = "Snoopy";
currentProfile.OtherProperty = "ABC";
currentProfile.Save();
Đó là lỗi của riêng tôi để xem hoàn toàn điểm cơ bản này, nhưng tôi cho rằng CurrentUser là một thuộc tính ngụ ý rằng đó là một đối tượng có thể được thao tác. Thay vào đó, nó phải được khai báo là GetCurrentUser()
.
Sẽ làm việc này mạo danh người dùng khác không? –
Mạo danh thường ngụ ý xác thực Windows, yêu cầu WindowsPrincipal. Mạo danh có thể được thực hiện từ mã thông báo bảo mật cho người dùng mạo danh hoặc từ thông tin đăng nhập. Do bối cảnh hiện tại không được xác thực, rất có thể không có cách nào để nhận mã thông báo bảo mật cho người dùng. Do đó, các lựa chọn duy nhất là mạo danh bằng thông tin đăng nhập. Nó có thể có thể xây dựng một WindowsPrincipal với danh tính thích hợp bằng cách gọi LogonUser (cung cấp mã biết thông tin đăng nhập cho người dùng windows). Tuy nhiên, tôi đã không cố gắng này, vì vậy tôi không thể xác minh nó sẽ nhất thiết phải làm việc. –
Đó là một lời giải thích cực kỳ hữu ích, cảm ơn bạn.Tạo một GenericPrincipal (từ FormsAuthenticationTicket của tôi) đã cho phép tôi đặt HttpContext.Current.User. Tuy nhiên, tôi vẫn không thể đặt giá trị Hồ sơ. Nếu tôi sử dụng ProfileBase.Create (Membership.GetUser(). UserName) .SetPropertyValue, không có gì xảy ra - nó không ném một ngoại lệ nữa, nhưng thuộc tính vẫn trống. Nếu tôi sử dụng HttpContext.Current.Profile.SetPropertyValue, nó nói rằng tôi không thể thiết lập thuộc tính trên một hồ sơ vô danh, ngụ ý rằng đây là những đối tượng Profile khác nhau mà tôi bằng cách nào đó cần phải hợp nhất. –