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

Blazor .NET6.0 WASM嵌入Power BI报表遇PlatformNotSupportedException错误

Blazor .NET 6 WASM嵌入Power BI报表解决方案

1. 核心思路

Blazor WASM是客户端运行环境,无法直接使用Power BI的.NET SDK(该SDK依赖服务器端运行时特性),因此必须通过后端API中转处理认证和令牌获取,前端仅负责调用后端拿到嵌入令牌后,通过Power BI的JavaScript嵌入库渲染报表。

2. 搭建后端API处理令牌请求

创建ASP.NET Core Web API(可与Blazor WASM同解决方案),完成Power BI服务主体认证和嵌入令牌生成:

  • 安装NuGet包:Microsoft.PowerBI.Api、Microsoft.Identity.Client
  • 在appsettings.json配置Power BI服务主体信息:
"PowerBI": {
  "ClientId": "你的服务主体ID",
  "ClientSecret": "你的服务主体密钥",
  "TenantId": "你的Azure租户ID",
  "WorkspaceId": "目标工作区ID",
  "ReportId": "目标报表ID"
}
  • 编写API接口:
[ApiController]
[Route("api/powerbi")]
public class PowerBiController : ControllerBase
{
    private readonly IConfiguration _config;

    public PowerBiController(IConfiguration config) => _config = config;

    [HttpGet("embed-token")]
    public async Task<IActionResult> GetEmbedToken()
    {
        var clientId = _config["PowerBI:ClientId"];
        var clientSecret = _config["PowerBI:ClientSecret"];
        var tenantId = _config["PowerBI:TenantId"];
        var workspaceId = _config["PowerBI:WorkspaceId"];
        var reportId = _config["PowerBI:ReportId"];

        // 获取服务主体访问令牌
        var authority = $"https://login.microsoftonline.com/{tenantId}";
        var scopes = new[] { "https://analysis.windows.net/powerbi/api/.default" };
        var app = ConfidentialClientApplicationBuilder
            .Create(clientId)
            .WithClientSecret(clientSecret)
            .WithAuthority(authority)
            .Build();
        var tokenResult = await app.AcquireTokenForClient(scopes).ExecuteAsync();

        // 生成报表嵌入令牌
        using var pbiClient = new PowerBIClient(new Uri("https://api.powerbi.com/"), new TokenCredentials(tokenResult.AccessToken));
        var embedToken = await pbiClient.Reports.GenerateTokenAsync(workspaceId, reportId, new GenerateTokenRequest(accessLevel: "View"));

        return Ok(new {
            EmbedToken = embedToken.Token,
            ReportId = reportId,
            WorkspaceId = workspaceId
        });
    }
}

3. Blazor WASM前端集成Power BI JS库

通过JavaScript互操作实现报表嵌入:

  • 在wwwroot/index.html引入Power BI JS脚本:
<script src="https://microsoft.github.io/PowerBI-JavaScript/dist/powerbi.min.js"></script>
  • 创建PowerBiReport.razor组件:
@page "/powerbi-report"
@inject HttpClient Http
@implements IAsyncDisposable

<div id="reportContainer" style="width: 100%; height: 800px;"></div>

@code {
    private IJSObjectReference? _interopModule;
    private IJSObjectReference? _reportInstance;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // 调用后端获取嵌入信息
            var embedData = await Http.GetFromJsonAsync<EmbedData>("api/powerbi/embed-token");
            if (embedData != null)
            {
                _interopModule = await JS.InvokeAsync<IJSObjectReference>("import", "./powerbi-interop.js");
                _reportInstance = await _interopModule.InvokeAsync<IJSObjectReference>("embedReport", 
                    "reportContainer", 
                    embedData.EmbedToken, 
                    embedData.ReportId, 
                    embedData.WorkspaceId);
            }
        }
    }

    public async ValueTask DisposeAsync()
    {
        if (_reportInstance != null)
        {
            await _reportInstance.InvokeVoidAsync("dispose");
            await _reportInstance.DisposeAsync();
        }
        if (_interopModule != null) await _interopModule.DisposeAsync();
    }

    private class EmbedData
    {
        public string EmbedToken { get; set; } = string.Empty;
        public string ReportId { get; set; } = string.Empty;
        public string WorkspaceId { get; set; } = string.Empty;
    }
}
  • 在wwwroot下创建powerbi-interop.js封装嵌入逻辑:
export async function embedReport(containerId, embedToken, reportId, workspaceId) {
    const embedConfig = {
        type: 'report',
        tokenType: 1,
        accessToken: embedToken,
        embedUrl: `https://app.powerbi.com/reportEmbed?reportId=${reportId}&groupId=${workspaceId}`,
        id: reportId,
        settings: {
            panes: { filters: { visible: false } }
        }
    };
    const container = document.getElementById(containerId);
    return powerbi.embed(container, embedConfig);
}

4. 关键注意事项

  • 安全防护:禁止在Blazor WASM客户端处理服务主体密钥或认证逻辑,必须通过后端中转,避免密钥泄露。
  • CORS配置:确保后端API允许Blazor WASM的跨域请求,在后端Program.cs添加:
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowWasm", policy => 
        policy.WithOrigins("https://localhost:5001") // 你的Blazor WASM地址
              .AllowAnyHeader()
              .AllowAnyMethod());
});
app.UseCors("AllowWasm");
  • 权限配置:确保Power BI服务主体拥有目标工作区和报表的Member或Admin权限,否则会导致令牌生成失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:15:54