【问题标题】:Executing async method on button click Blazor Server在按钮上执行异步方法单击 Blazor 服务器
【发布时间】:2020-11-20 15:32:40
【问题描述】:

我试图在按下按钮时执行异步方法。代码编译没有问题,但是当按钮被点击时,该方法永远不会被调用。我已经使用了我可以使用的所有 google fu,但无济于事。我在语法上做错了吗?是我忘记导入某些东西还是我误解了它的工作原理?

  @foreach (Data.Course cor in CourseList)
                    { 
/...
<button class="btn btn-outline-primary" @onclick="@(async () => await EnrollCourse(cor.CourseId))">
                                        Enroll
                                    </button>
}

@functions{
    private async Task EnrollCourse(int corid)
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        string userid = authState.User.Identity.Name;
        await _db.EnrollCourse(corid, userid);
        NavigationManager.NavigateTo($"/course/{corid}");
        
    }



}

【问题讨论】:

  • 字符串用户 ID = authState.User.Identity.Name;这不是电子邮件不是身份证吗?
  • 你怎么知道这个方法从来没有被调用过?
  • 是的,我用调试器验证了该方法永远不会被执行,数据也没有填充到数据库中
  • @functions 还能用吗?您使用的是哪个 Blazor 版本?
  • @HenkHolterman我在代码块和功能块中都试过了,从我看到的大多数人看来似乎把这样的代码放在功能块中。无论最新版本是什么

标签: c# razor blazor blazor-server-side razor-components


【解决方案1】:

对于在 google 上遇到此问题的任何人,我最终将按钮设置为重定向到运行代码并重定向到最终页面的不同页面。

<div class="button">
    <a href="/enroll/@cor.CourseId">Enroll</a>
</div>
@page "/enroll/{course}"
@inject Data.CourseData _db
@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject Microsoft.AspNetCore.Identity.UserManager<Microsoft.AspNetCore.Identity.IdentityUser> userManager
@using System.Security.Claims


@code {
    [Parameter]
    public string course { get; set; }
    protected override async Task OnInitializedAsync()
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();

        var user = await userManager.GetUserAsync(authState.User);
        if (user != null)
        {
            string userid = user.Id;
            await _db.EnrollCourse(Int32.Parse(course), userid);
            NavigationManager.NavigateTo("/course/" + Int32.Parse(course));


        }
    }

}

【讨论】:

    【解决方案2】:

    请注意我是如何收集用户 ID 的。我希望这有帮助。您的用户管理器也可能是 UserManager&lt;ApplicationUser&gt; 类型...

        @inject UserManager<ApplicationUser> userManager
        @using System.Security.Claims
        .....
        <AuthorizeView>
              @foreach (Data.Course cor in CourseList)
                        { 
    /...
    <button class="btn btn-outline-primary" @onclick="@(async () => await EnrollCourse(cor.CourseId,context.User))">
                                            Enroll
                                        </button>
    }
        </AuthorizeView>
    @functions{
         private async Task EnrollCourse(int corid, ClaimsPrincipal identity)
         {
    
            var user = await userManager.GetUserAsync(identity);
    
            var userid = user.Id;
            await _db.EnrollCourse(corid, userid);
            NavigationManager.NavigateTo($"/course/{corid}");
            
         }
    
    
    
    }
    

    【讨论】:

    • 是的,我翻阅了文档,找不到获取实际用户 ID 的方法,所以我只好改用用户名。我不确定您的实现引用的是什么用户 ID,因为在我的数据库中,用户 ID 是字符串而不是 int。我通过 @inject AuthenticationStateProvider AuthenticationStateProvider 使用默认的 authenticationstateprovider 库
    • @MaxTE7 将其切换到作为字符串键的 UserManager。 blazer 服务器端的个人帐户必须是整数。注入 AuthenticationStateProvider 也应该有效。如果用户不能使用该功能,为什么要显示按钮。这就是我使用 的原因。它提供了上下文,因此无需调用 GetAuthenticationStateAsync()。
    • 我实际上是在授权视图中创建按钮,因此我可以使用您获取上下文的方法,但是,当我尝试注入 Microsoft.AspNetCore.Identity.UserManager&lt;ApplicationUser&gt; 时,我得到了一个未找到命名空间的错误。如果有帮助,我将使用 blazor 中内置的基于默认用户的身份验证
    • 我想通了。 var user = userManager.GetUserAsync(identity); 应该是 var user = await userManager.GetUserAsync(identity);。然后正确检索用户
    • 仅供参考:var userId = identity.FindFirst(c => c.Type == "sub")?.Value;在客户端工作
    猜你喜欢
    • 2019-08-25
    • 2020-02-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2022-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多