You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor WASM功能管理配置求助:官方包读取配置异常

Blazor WASM 功能管理配置方案

针对你的问题,核心原因是Blazor WASM运行在客户端,无法直接读取服务器端的appsettings.json,需要先将服务器的功能标志传递到客户端,再结合Microsoft.FeatureManagement包实现功能控制,以下是具体方案:

一、传递服务器功能配置到客户端

托管模式(Blazor WASM Hosted)实现方式

在服务器项目的Pages/_Host.cshtml中,将FeatureManagement配置序列化为全局JS变量,供客户端读取:

<script>
    window.featureSettings = @Json.Serialize(Configuration.GetSection("FeatureManagement"));
</script>

客户端配置提供者

在WASM项目中创建自定义配置提供者,读取上述全局变量:

using Microsoft.Extensions.Configuration;
using Microsoft.JSInterop;

public class ClientFeatureConfigProvider : ConfigurationProvider
{
    private readonly IJSRuntime _jsRuntime;

    public ClientFeatureConfigProvider(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime;
    }

    public override void Load()
    {
        var featureConfig = _jsRuntime.InvokeAsync<Dictionary<string, bool>>("eval", "window.featureSettings").Result;
        foreach (var kvp in featureConfig)
        {
            Data[$"FeatureManagement:{kvp.Key}"] = kvp.Value.ToString();
        }
    }
}

然后在WASM项目的Program.cs中注册配置提供者和功能管理服务:

var builder = WebAssemblyHostBuilder.CreateDefault(args);

// 添加自定义配置提供者
builder.Configuration.Add(new ClientFeatureConfigProvider(builder.Services.BuildServiceProvider().GetRequiredService<IJSRuntime>()));

// 注册功能管理服务
builder.Services.AddFeatureManagement();

builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

await builder.Build().RunAsync();

此时注入IFeatureManager就能正确读取服务器传递的功能标志了。

二、页面/组件级功能锁定实现

方式1:FeatureGate 包裹组件

创建通用的FeatureGate组件,用于控制子内容的显示:

@inject IFeatureManager FeatureManager
@if (_isFeatureEnabled)
{
    @ChildContent
}

@code {
    [Parameter, Required]
    public string FeatureName { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    private bool _isFeatureEnabled;

    protected override async Task OnInitializedAsync()
    {
        _isFeatureEnabled = await FeatureManager.IsEnabledAsync(FeatureName);
    }
}

使用示例:

<FeatureGate FeatureName="NewPaymentFlow">
    <NewPaymentComponent />
</FeatureGate>

方式2:页面级特性标记控制

自定义特性标记,结合组件激活器实现页面级拦截:

  1. 定义特性:
[AttributeUsage(AttributeTargets.Class)]
public class FeatureLockedAttribute : Attribute
{
    public string FeatureName { get; }

    public FeatureLockedAttribute(string featureName)
    {
        FeatureName = featureName;
    }
}
  1. 实现自定义组件激活器:
using Microsoft.AspNetCore.Components;
using Microsoft.FeatureManagement;
using System.Reflection;

public class FeatureGateActivator : ComponentActivator
{
    private readonly IServiceProvider _serviceProvider;

    public FeatureGateActivator(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public override IComponent CreateInstance(Type componentType)
    {
        var lockAttr = componentType.GetCustomAttribute<FeatureLockedAttribute>();
        if (lockAttr != null)
        {
            var featureManager = _serviceProvider.GetRequiredService<IFeatureManager>();
            var isEnabled = featureManager.IsEnabledAsync(lockAttr.FeatureName).GetAwaiter().GetResult();
            
            if (!isEnabled)
            {
                // 返回功能未启用提示组件
                return _serviceProvider.GetRequiredService<FeatureNotEnabledComponent>();
            }
        }
        return base.CreateInstance(componentType);
    }
}
  1. 在Program.cs注册激活器:
builder.Services.AddSingleton<IComponentActivator, FeatureGateActivator>();
  1. 标记页面组件:
[FeatureLocked("AdminDashboard")]
public partial class AdminDashboardPage
{
    // 页面逻辑
}

当访问该页面时,若对应功能未启用,会自动显示FeatureNotEnabledComponent。

内容的提问来源于stack exchange,提问作者LordGhandi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:50:59