Blazor服务器端,剃刀页面上的ExternalRegister按钮



有可能有按钮"外部注册";放在里面。剃须刀页(服务器端(?

下面的代码来自ExternalRegister.cs.html,但我希望将这两个注册按钮(谷歌、脸书(作为Start.razor页面的一部分。这可能吗?

@model Aplication.Areas.Identity.Pages.Account.ExternalRegisterModel
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
<div>
<p>
@foreach (var provider in Model.ExternalLogins)
{
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
}
</p>
</div>
</form>

是的,在剃刀页面中可以有这些按钮。

当然,要做到这一点,您需要能够枚举可用的提供者,这意味着您需要将它们从传递到Blazor应用程序_Host.cshtml(或任何您托管Blazor应用程序的地方(

注意:不能传递AuthenticationScheme的列表,因为.NET不会串行化它们,这就是为什么我将它们转换为DTOExternalProvider

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@inject SignInManager<IdentityUser> _signInManager
@{
var state = new InitialApplicationState
{
XsrfToken = Xsrf.GetAndStoreTokens(HttpContext).RequestToken,
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
.ToList()
.Select(scheme=>
new ExternalProvider {Name=scheme.Name, DisplayName=scheme.DisplayName}
)
};
}
<component type="typeof(App)" param-InitialState="state" render-mode="ServerPrerendered" />

InitialApplicationStateExternalProvider是简单的DTO类

public class InitialApplicationState
{
public string XsrfToken { get; set; }
public IEnumerable<ExternalProvider> ExternalLogins { get; set; }
}
public class ExternalProvider
{
public string Name { get; set; }
public string DisplayName { get; set; }
}

现在,您需要在您的Blazor代码中接收此数据,作为App.razor组件上的Parameter

@inject InitialApplicationState InitialStateService
@code {
[Parameter] public InitialApplicationState InitialState { get; set; } = default;
protected override Task OnInitializedAsync()
{
InitialStateService.XsrfToken = InitialState.XsrfToken;
InitialStateService.ExternalLogins = InitialState.ExternalLogins;
return base.OnInitializedAsync();
}
}

我们在这里所做的只是声明将接收我们的InitialApplicationStateParameterInitialState,然后我们将该状态存储在服务InitialStateService中,该服务在startup.cs中配置为Scoped依赖项。

builder.Services.AddScoped<InitialApplicationState>();

现在,我们在Blazor的DI容器中有一个服务,其中包含可用的外部身份验证提供商列表和我们的防伪令牌。

我们可以在Blazor中任何需要的地方注入InitialApplicationState,例如Index.razor,并枚举ExternalLogins以呈现按钮

Blazor中对该表单的声明略有不同,因为我们没有asp*指令:

@inject InitialApplicationState InitialStateService
<form id="external-account" 
action="/Identity/Account/ExternalLogin" 
method="post">
<div>
<p>
@foreach (var provider in InitialStateService.ExternalLogins)
{
<button type="submit" 
name="provider" 
value="@provider.Name" 
title="Log in using your @provider.DisplayName account">
@provider.DisplayName
</button>
}
</p>
</div>
<input name="__RequestVerificationToken" type="hidden"
value="@InitialStateService.XsrfToken">
</form>

我认为最好的策略是在Razor PageModel(Code Behind(中定义两个OnPost方法。例如:

public void OnPostFaceBook(ExternalLogin provider)
{
//your code here
}
public void OnPostGoogle(ExternalLogin provider)
{
//your code here
}

在.cs.html文件中,为每个表单放置两个单独的表单,并添加参数asp页面处理程序到每个提交按钮。例如:

<button type="submit" class="btn btn-primary" value="FaceBook" value="FaceBook" asp-page-handler="FaceBook">Log in using your FaceBook account</button>

以及其他形式:

<button type="submit" class="btn btn-primary" value="Google" value="Google" asp-page-handler="Google">Log in using your Google account</button>

相关内容

  • 没有找到相关文章

最新更新