我已经提出了类似的问题,关于较旧的MVC版本和会员资格,但这些解决方案不适用于Idendity和MVC 6.
我想在_LoginPartial.cshtml文件中显示用户的第一个名字。因此,我想要访问当前登录用户的ApplicationUser.FirstName而不是"Hello " + User.Identity.GetUserName() + "!"
。这样做的最佳方式是什么?
答案 0 :(得分:2)
我更好地提出了一个解决方案,因为每次请求只需要搜索一个配置文件。
首先:创建用户服务
public interface IUserProfileLoader
{
Task<ApplicationUser> GetCurrentApplicationUser(ClaimsPrincipal user);
}
public class UserServices : IUserProfileLoader
{
private readonly UserManager<ApplicationUser> _userManager;
private ApplicationUser _CurrentUser;
public UserServices([FromServices]UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task<ApplicationUser> GetCurrentApplicationUser(ClaimsPrincipal user)
{
if (_CurrentUser == null)
{
_CurrentUser = await _userManager.FindByIdAsync(user.GetUserId());
}
return _CurrentUser;
}
}
然后注册服务
在 ConfigureServices 中添加以下内容:
// Add user profile services.
services.AddScoped<IUserProfileLoader, UserServices>();
用于视图
注入服务:
@inject IUserProfileLoader UserServices
然后像这样访问属性:
@((await UserServices.GetCurrentApplicationUser(User)).Email)
在其他地方使用......
您可以使用
在操作(例如)中访问该服务[FromServices]IUserProfileLoader UserServices
我希望这会有所帮助。
答案 1 :(得分:1)
对于更简单的修复,您可以将服务直接注入视图以检索ApplicationUser
。
@inject UserManager<ApplicationUser> MyManager
@{
var applicationUser = MyManager.FindByIdAsync(User.Identity.GetUserId());
}
另请注意,如果您想要从所有观看中访问@inject
,可以在_ViewStart.cshtml
中添加UserManager<ApplicationUser>
。
答案 2 :(得分:0)
我已经使用组件实现了这个解决方案,但它似乎有点矫枉过正。
的视图\ Shared_LoginPartial.cshtml 强>
...
@await Component.InvokeAsync("FirstName", User.Identity.GetUserId())
...
的视图\共享\组件\姓\ Default.cshtml 强>
@model Models.ApplicationUser
@Html.ActionLink("Hello " + Model.FirstName + "!", "Manage", "Account", routeValues: null, htmlAttributes: new { title = "Manage" })
的 ViewComponents \ FirstNameViewComponent.cs 强>
public class FirstNameViewComponent : ViewComponent
{
private readonly IUserService m_userService;
public FirstNameViewComponent(IUserService userService)
{
m_userService = userService;
}
public async Task<IViewComponentResult> InvokeAsync(string userId)
{
Models.ApplicationUser user = await m_userService.FindUserByIdAsync(userId);
return View(user);
}
}
<强>服务\ UserService.cs 强>
public interface IUserService
{
Task<ApplicationUser> FindUserByIdAsync(string id);
}
public class UserService : IUserService
{
private readonly UserManager<ApplicationUser> m_userManager;
public UserService(UserManager<ApplicationUser> userManager)
{
m_userManager = userManager;
}
public Task<ApplicationUser> FindUserByIdAsync(string id)
{
return m_userManager.FindByIdAsync(id);
}
}
的 Startup.cs 强>
...
services.AddScoped<IUserService, UserService>();
...
我想我可以在登录后更新用户服务并存储ApplicationUser,并在注销后删除它,但我想知道是否有另一种解决方法。另外我不确定scoped服务是否是最好的,我没有找到一种方法来进行会话,而不是请求作用域。
答案 3 :(得分:0)
我找到了另一个解决方案,implementing custom IPrincipal。我认为它是最好的,因为每次我需要这些信息时它都不需要用户搜索。