Blazor使用AuthorizeView时RenderComponent渲染失败问题求助
问题根源
AuthorizeView组件依赖级联的Task<AuthenticationState>参数,而使用HtmlRenderer直接渲染BillView时,没有提供这个级联参数,导致抛出Authorization requires a cascading parameter of type Task<AuthenticationState>错误。
修复步骤
1. 修正BillView组件的拼写错误
你的BillView里有拼写错误:<Authroized>应该改为<Authorized>,否则即使认证逻辑正常,也无法正确渲染授权内容。
修正后的BillView:
<AuthorizeView Roles="Admin, Reception"> <Authorized> <p> This is a bill.</p> </Authorized> <NotAuthorized> <p>You are not authorized.</p> </NotAuthorized> </AuthorizeView>
2. 扩展BlazorRenderer,添加带认证状态的渲染方法
修改BlazorRenderer类,新增一个方法,在渲染目标组件时包裹CascadingAuthenticationState,提供必需的级联参数:
internal class BlazorRenderer { private readonly HtmlRenderer _htmlRenderer; public BlazorRenderer(HtmlRenderer htmlRenderer) { _htmlRenderer = htmlRenderer; } // 保留原有渲染方法 public Task<string> RenderComponent<T>() where T : IComponent => RenderComponent<T>(ParameterView.Empty); public Task<string> RenderComponent<T>(Dictionary<string, object?> dictionary) where T : IComponent => RenderComponent<T>(ParameterView.FromDictionary(dictionary)); private Task<string> RenderComponent<T>(ParameterView parameters) where T : IComponent { return _htmlRenderer.Dispatcher.InvokeAsync(async () => { HtmlRootComponent output = await _htmlRenderer.RenderComponentAsync<T>(parameters); return output.ToHtmlString(); }); } // 新增:带认证状态的渲染方法 public Task<string> RenderComponentWithAuth<T>(AuthenticationState authState) where T : IComponent { return _htmlRenderer.Dispatcher.InvokeAsync(async () => { // 构建包含级联认证状态的渲染片段 var renderFragment = (RenderFragment)(builder => { builder.OpenComponent<CascadingAuthenticationState>(0); builder.AddComponentParameter(1, "ChildContent", (RenderFragment)(childBuilder => { childBuilder.OpenComponent<T>(0); childBuilder.CloseComponent(); })); builder.CloseComponent(); }); // 用临时组件承载渲染片段并渲染 var tempComponent = new TempComponent { ChildContent = renderFragment }; HtmlRootComponent output = await _htmlRenderer.RenderComponentAsync<TempComponent>(ParameterView.Empty); return output.ToHtmlString(); }); } // 临时组件:用于承载自定义渲染片段 private class TempComponent : ComponentBase { [Parameter] public RenderFragment? ChildContent { get; set; } protected override void BuildRenderTree(RenderTreeBuilder builder) { ChildContent?.Invoke(builder); } } }
3. 在打印方法中传递当前认证状态
在调用渲染方法时,先获取当前用户的AuthenticationState,再传递给新增的RenderComponentWithAuth方法:
@inject AuthenticationStateProvider AuthStateProvider @inject BlazorRenderer BlazorRenderer @inject IJSRuntime JSRuntime private async Task PrintComponent() { // 获取当前用户的真实认证状态 var authState = await AuthStateProvider.GetAuthenticationStateAsync(); // 渲染带认证上下文的组件 var htmlout = await BlazorRenderer.RenderComponentWithAuth<BillView>(authState); await JSRuntime.InvokeVoidAsync("printComponent1", htmlout); }
替代方案:模拟认证状态(用于测试)
如果不需要真实用户的认证状态,也可以模拟一个AuthenticationState来渲染指定角色的内容:
// 模拟拥有Admin角色的用户 var claims = new List<Claim> { new Claim(ClaimTypes.Name, "Test User"), new Claim(ClaimTypes.Role, "Admin") }; var identity = new ClaimsIdentity(claims, "TestAuth"); var authState = new AuthenticationState(new ClaimsPrincipal(identity)); var htmlout = await BlazorRenderer.RenderComponentWithAuth<BillView>(authState);
内容的提问来源于stack exchange,提问作者user3656651
相关产品推荐
相关产品推荐

