制作自定义 Blazor 组件
Making a Custom Blazor component
我从 Blazor 的乐趣开始,
我首先要尝试的事情之一是将我的菜单项包装到自定义组件中,以使导航更具可读性。
我尝试了一些方法:
文件:Components\MenuItem.razor
<AuthorizeView Roles="@Roles">
<li class="nav-item px-3">
<NavLink class="nav-link" href="@Link">
<span class="oi oi-task" aria-hidden="true"></span> @Text
</NavLink>
</li>
</AuthorizeView>
@code {
public string Link { get; set; }
public string Text { get; set; }
public string Roles { get; set; }
}
但是如果我在导航中使用组件而不是相同的内容,那么当我 运行 应用程序时不会加载任何内容。
在我的导航菜单中,添加以下内容
<VM.Web.Components.MenuItem Text="Approve user requests" Link="/users/pending-approval" Roles="ADMIN, CREW" />
停止加载页面(我没有看到任何错误)
但直接在导航菜单中的以下内容有效
<AuthorizeView Roles="ADMIN, CREW">
<li class="nav-item px-3">
<NavLink class="nav-link" href="/users/pending-approval">
<span class="oi oi-task" aria-hidden="true"></span> Approve user requests
</NavLink>
</li>
</AuthorizeView>
更新,
问题是我缺少 [Parameter] 装饰,之后它起作用了
最终的组件代码如下所示
<AuthorizeView Roles="@Roles">
<li class="nav-item px-3">
<NavLink class="nav-link" href="@Link">
<span class="@SpanClasses" aria-hidden="true"></span> @Text
</NavLink>
</li>
</AuthorizeView>
@code {
[Parameter]
public string Link { get; set; }
[Parameter]
public string Text { get; set; }
[Parameter]
public string Roles { get; set; }
[Parameter]
public string SpanClasses { get; set; }
}
作为参考,身份验证模块是由另一个程序员实现的并且可以工作:),它是这样配置的
builder.Services
.AddOidcAuthentication(options =>
{
builder.Configuration.Bind("oidc", options.ProviderOptions);
options.UserOptions.RoleClaim = "role";
options.AuthenticationPaths.LogInFailedPath = "/";
options.AuthenticationPaths.LogOutSucceededPath = "/";
options.AuthenticationPaths.LogOutCallbackPath = "/authentication/logout-callback";
})
.AddAccountClaimsPrincipalFactory<ArrayClaimsPrincipalFactory<RemoteUserAccount>>();
AuthorityConnection = builder.Configuration.GetSection("oidc:Authority").Value;
directly in the navmenu works
<AuthorizeView Roles="ADMIN, CREW">
告诉我你的角色正在传递给 WebAssembly
我发现这在将菜单项作为数据传递时很有用。我需要迎合未授权、授权和我添加的角色。
如果任何用户具有多个角色,则还需要 Enet 提供的声明工厂,因为他们以逗号分隔格式到达。
OptionalRolesAuthorizeView.razor
@if (string.IsNullOrWhiteSpace(Roles) && RequireAuthentication == false)
{
@ChildContent
}
else
{
<AuthorizeView Roles="@Roles">
@ChildContent
</AuthorizeView>
}
@code {
[Parameter]
public bool RequireAuthentication { get; set; }
[Parameter]
public string Roles { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
}
MenuItemView.razor
<OptionalRolesAuthorizeView RequireAuthentication="@Model.RequireAuthentication" Roles="@Model.Roles">
<li class="nav-item px-3">
<NavLink class="nav-link" href="@Model.Href" Match="@Model.Match">
<span class="@Model.IconClass" aria-hidden="true"></span> @Model.Label
</NavLink>
</li>
</OptionalRolesAuthorizeView>
@code {
[Parameter]
public MenuItem Model { get; set; }
}
MenuItem.cs
using Microsoft.AspNetCore.Components.Routing;
public class MenuItem
{
public string Label { get; set; }
public string Href { get; set; }
public string IconClass { get; set; }
public bool RequireAuthentication { get; set; }
public NavLinkMatch Match { get; set; }
public string Roles { get; set; }
}
你还应该看看 policies。
我从 Blazor 的乐趣开始, 我首先要尝试的事情之一是将我的菜单项包装到自定义组件中,以使导航更具可读性。
我尝试了一些方法:
文件:Components\MenuItem.razor
<AuthorizeView Roles="@Roles">
<li class="nav-item px-3">
<NavLink class="nav-link" href="@Link">
<span class="oi oi-task" aria-hidden="true"></span> @Text
</NavLink>
</li>
</AuthorizeView>
@code {
public string Link { get; set; }
public string Text { get; set; }
public string Roles { get; set; }
}
但是如果我在导航中使用组件而不是相同的内容,那么当我 运行 应用程序时不会加载任何内容。
在我的导航菜单中,添加以下内容
<VM.Web.Components.MenuItem Text="Approve user requests" Link="/users/pending-approval" Roles="ADMIN, CREW" />
停止加载页面(我没有看到任何错误) 但直接在导航菜单中的以下内容有效
<AuthorizeView Roles="ADMIN, CREW">
<li class="nav-item px-3">
<NavLink class="nav-link" href="/users/pending-approval">
<span class="oi oi-task" aria-hidden="true"></span> Approve user requests
</NavLink>
</li>
</AuthorizeView>
更新, 问题是我缺少 [Parameter] 装饰,之后它起作用了
最终的组件代码如下所示
<AuthorizeView Roles="@Roles">
<li class="nav-item px-3">
<NavLink class="nav-link" href="@Link">
<span class="@SpanClasses" aria-hidden="true"></span> @Text
</NavLink>
</li>
</AuthorizeView>
@code {
[Parameter]
public string Link { get; set; }
[Parameter]
public string Text { get; set; }
[Parameter]
public string Roles { get; set; }
[Parameter]
public string SpanClasses { get; set; }
}
作为参考,身份验证模块是由另一个程序员实现的并且可以工作:),它是这样配置的
builder.Services
.AddOidcAuthentication(options =>
{
builder.Configuration.Bind("oidc", options.ProviderOptions);
options.UserOptions.RoleClaim = "role";
options.AuthenticationPaths.LogInFailedPath = "/";
options.AuthenticationPaths.LogOutSucceededPath = "/";
options.AuthenticationPaths.LogOutCallbackPath = "/authentication/logout-callback";
})
.AddAccountClaimsPrincipalFactory<ArrayClaimsPrincipalFactory<RemoteUserAccount>>();
AuthorityConnection = builder.Configuration.GetSection("oidc:Authority").Value;
directly in the navmenu works
<AuthorizeView Roles="ADMIN, CREW">
告诉我你的角色正在传递给 WebAssembly
我发现这在将菜单项作为数据传递时很有用。我需要迎合未授权、授权和我添加的角色。
如果任何用户具有多个角色,则还需要 Enet 提供的声明工厂,因为他们以逗号分隔格式到达。
OptionalRolesAuthorizeView.razor
@if (string.IsNullOrWhiteSpace(Roles) && RequireAuthentication == false)
{
@ChildContent
}
else
{
<AuthorizeView Roles="@Roles">
@ChildContent
</AuthorizeView>
}
@code {
[Parameter]
public bool RequireAuthentication { get; set; }
[Parameter]
public string Roles { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
}
MenuItemView.razor
<OptionalRolesAuthorizeView RequireAuthentication="@Model.RequireAuthentication" Roles="@Model.Roles">
<li class="nav-item px-3">
<NavLink class="nav-link" href="@Model.Href" Match="@Model.Match">
<span class="@Model.IconClass" aria-hidden="true"></span> @Model.Label
</NavLink>
</li>
</OptionalRolesAuthorizeView>
@code {
[Parameter]
public MenuItem Model { get; set; }
}
MenuItem.cs
using Microsoft.AspNetCore.Components.Routing;
public class MenuItem
{
public string Label { get; set; }
public string Href { get; set; }
public string IconClass { get; set; }
public bool RequireAuthentication { get; set; }
public NavLinkMatch Match { get; set; }
public string Roles { get; set; }
}
你还应该看看 policies。