繁体   English   中英

为什么 UserManager.GetUserAsync 不返回?

[英]why does UserManager.GetUserAsync not return?

为什么 UserManager.GetUserAsync 不返回?

当我在关于页面上手动单击时,将在 blazor UI 中访问属性 IsAdmin。 我不明白为什么对 GetUSerAsync 的调用没有返回。 有什么线索或错误吗? 为简单起见,我删除了锁定代码。 (没有也不起作用)

关于.razor.cs

using System.Collections.Generic;
using System.Linq;
using Common.Server.Logic.Services;
using Common.Shared.Extensions;
using Microsoft.AspNetCore.Components;

namespace Common.Server.UI.Pages
{
    public partial class About : ComponentBase
    {
#nullable disable
        [Inject]
        private UserSessionInfo UserSession { get; set;  }

        private string IsAdminText { get; set; }
        private IEnumerable<string> UserRoleNames { get; set; } = Enumerable.Empty<string>();

#nullable restore

        protected override void OnInitialized()
        {
            IsAdminText = UserSession.IsAdmin.Format();
            UserRoleNames = UserSession.UserRoles;
        }
    }
}

用户会话信息.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AspNetCore.ServiceRegistration.Dynamic.Interfaces;
using Common.Server.Logic.Bases;
using Common.Shared;
using Common.Shared.Extensions;
using Common.Shared.Models.Logging.Bases;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;

namespace Common.Server.Logic.Services
{
    public class UserSessionInfo : LockingBase, IHasUsername, IScopedService
    {
        public DateTime LoginAt { get; set; }

        private UserManager<IdentityUser> UserManager { get; }
        private AuthenticationStateProvider AuthenticationStateProvider { get; }

        public IEnumerable<string> UserRoles { get; private set; } = Enumerable.Empty<string>();

        private string? _username;
        public string? Username
        {
            get
            {
                CheckInitialized();

                return _username;
            }
        }

        private bool _isAdmin;
        public bool IsAdmin
        {
            get
            {
                CheckInitialized();

                return _isAdmin;
            }
        }

        public UserSessionInfo(IServiceProvider serviceProvider)
        {
            UserManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();
            AuthenticationStateProvider = serviceProvider.GetRequiredService<AuthenticationStateProvider>();
        }

        private void CheckInitialized()
        {
            if (_username is null)
                // double lock
                SyncLock.Lock(async () => await InitializeAsync()).GetAwaiter().GetResult();
        }

        private async Task InitializeAsync()
        {
            var claimsPrincipal = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;

            var user = await UserManager.GetUserAsync(claimsPrincipal); // Does not return
            _isAdmin = await UserManager.IsInRoleAsync(user, Const.Authorization.Roles.AdminRoleName);

            UserRoles = await UserManager.GetRolesAsync(user);

            var username = await UserManager.GetUserNameAsync(user);
            Interlocked.Exchange(ref _username, username);
        }
    }
}

也(startup.cs):

services.AddDefaultIdentity<IdentityUser>()
                .AddRoles<IdentityRole>()
                .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<IdentityUser, IdentityRole>>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders()
                .AddDefaultUI();

services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();

services.AddScoped<UserSessionInfo>();

当异步方法没有返回时, .GetAwaiter().GetResult()是第一个嫌疑人。

很可能您的调用代码(渲染器?)正在让您的 Username 和 IsAdmin 属性重叠,然后您就会出现死锁。 但是如果没有看到整个调用链,我们就无法确定。

根据经验,您不需要锁定或 GetResult(或 .Wait()、.Result)。 当你认为你这样做时,可能是时候备份了。

最后我找到了解决方案。 (以及它不起作用的原因)

问题是我在 OnInitialized 回调期间访问了 IsAdmin 而不是 OnInitializedAsync。

将 IsAdmin 的访问权限放入 OnInitializedAsync 一切正常!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM