【问题标题】:Get ApplicationUser from Partial View从局部视图中获取 ApplicationUser
【发布时间】:2015-01-28 16:06:55
【问题描述】:

我问过关于旧 MVC 版本和成员资格的类似问题,但这些解决方案不适用于 Idendity 和 MVC 6。
我想在 _LoginPartial.cshtml 文件中显示用户的名字。因此,我想访问当前登录用户的 ApplicationUser.FirstName 而不是 "Hello " + User.Identity.GetUserName() + "!"。最好的方法是什么?

【问题讨论】:

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


    【解决方案1】:

    我认为更好的解决方案是因为每个请求只需要一次搜索配置文件。

    首先:创建用户服务

    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)
    

    用于其他地方...

    您可以在 Action 中访问服务(例如),使用:

    [FromServices]IUserProfileLoader UserServices
    

    我希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      为了更简单的修复,您可以将服务直接注入您的视图以检索ApplicationUser。

      @inject UserManager<ApplicationUser> MyManager
      
      @{
          var applicationUser = MyManager.FindByIdAsync(User.Identity.GetUserId());
      }
      

      另外请注意,如果您想从所有视图访问您的UserManager&lt;ApplicationUser&gt;,您可以在您的_ViewStart.cshtml 中添加@inject。

      【讨论】:

      • 是的,它看起来更简单。登录后保存当前应用用户不是更好吗?
      • 不确定您所说的“保存当前应用用户”是什么意思。
      • 好吧,保存所需的信息,这样应用就不会在每次需要显示用户名时都使用数据库
      • 哦,当然,我只是在展示,如果您要采用这种方法,而不是在视图组件等中包装位,您只需将管理用户的服务拉入您的页面即可。跨度>
      • GetUserId() 不是 Identity 方法。你可以做 User.Identity.Name。
      【解决方案3】:

      我已经使用组件实现了这个解决方案,但这似乎有点过头了。

      Views\Shared_LoginPartial.cshtml

      ...
      @await Component.InvokeAsync("FirstName", User.Identity.GetUserId())
      ...
      


      Views\Shared\Components\FirstName\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);
          }
      }
      


      Services\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,并在注销后将其删除,但我想知道是否有其他方法可以解决这个问题。此外,我不确定范围服务是否是这里最好的,我没有找到使它成为会话的方法,而不是请求范围。

      【讨论】:

        【解决方案4】:

        我找到了另一个解决方案,implementing custom IPrincipal。我认为这是最好的,因为它不需要每次我需要这些信息时都需要用户搜索。

        【讨论】:

          猜你喜欢
          • 2017-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-05
          • 2021-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多