从Partial View获取ApplicationUser

时间:2015-01-28 16:06:55

标签: c# asp.net-mvc asp.net-identity-2 asp.net-core-mvc

我已经提出了类似的问题,关于较旧的MVC版本和会员资格,但这些解决方案不适用于Idendity和MVC 6. 我想在_LoginPartial.cshtml文件中显示用户的第一个名字。因此,我想要访问当前登录用户的ApplicationUser.FirstName而不是"Hello " + User.Identity.GetUserName() + "!"。这样做的最佳方式是什么?

4 个答案:

答案 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。我认为它是最好的,因为每次我需要这些信息时它都不需要用户搜索。