分享方式:


教學課程:將 Power BI 報表內嵌至客戶的應用程式

在本教學課程中,您將了解如何在 .NET 5.0 應用程式中內嵌 Power BI 報表,作為「為您的客戶內嵌」(也稱為「應用程式擁有資料」) 解決方案的一部分。 在「為您的客戶內嵌」解決方案中,應用程式使用者不需要登入 Power BI 或擁有 Power BI 授權。

在本教學課程中,您會了解如何內嵌:

  • Power BI 報表。
  • 在「為您的客戶內嵌」應用程式中。
  • 透過使用服務主體內嵌
  • 透過使用 .NET 5.0。
  • 透過 Microsoft.Identity.Web 程式庫 (.NET Core 中也支援此程式庫)。

注意

本教學課程中使用的完整解決方案可從 DOTNET5-AppOwnsData-Tutorial GitHub 存放庫取得。

必要條件

資源

在本教學課程中,您會使用:

方法

若要在「為您的客戶內嵌」解決方案中內嵌 Power BI 內容,請遵循下列步驟:

  1. 設定您的 Microsoft Entra 應用程式和服務主體

  2. 取得內嵌參數值

  3. 新增必要的 NuGet 套件

  4. 啟用伺服器端驗證

  5. 建置應用程式的用戶端

  6. 執行您的應用程式

步驟 1 - 設定您的 Microsoft Entra 應用程式和服務主體

在此教學課程中,您會使用服務主體來向 Microsoft Entra ID 進行驗證。 您也需要 Microsoft Entra 應用程式,這可讓您產生 Microsoft Entra 權杖。 透過使用 Microsoft Entra 權杖,您的 Web 應用程式可以呼叫 Power BI REST API並內嵌 Power BI 項目,例如報表、儀表板,以及磚。

請遵循服務主體指示來建立 Microsoft Entra 應用程式,並讓應用程式的服務主體能夠與您的 Power BI 內容搭配使用。

步驟 2 - 取得內嵌參數值

若要內嵌您的報表,您需要下列值:

網域和租用戶識別碼

如果您不知道網域或租用戶識別碼,請參閱尋找 Microsoft Entra 租用戶識別碼和主要網域名稱

注意

若要為不同租用戶上的使用者內嵌內容 (來賓使用者),您需要調整 authorityUri 參數。

Client ID

若要取得用戶端識別碼 GUID (也稱為「應用程式識別碼」),請遵循下列步驟:

  1. 登入 Microsoft Azure

  2. 搜尋應用程式註冊,然後選取 [應用程式註冊] 連結。

  3. 選取您用於內嵌 Power BI 內容的 Microsoft Entra 應用程式。

  4. 從 [概觀] 區段中,複製 [應用程式 (用戶端) 識別碼] GUID。

用戶端密碼

若要取得用戶端密碼,請遵循下列步驟:

  1. 登入 Microsoft Azure

  2. 搜尋應用程式註冊,然後選取 [應用程式註冊] 連結。

  3. 選取您用於內嵌 Power BI 內容的 Microsoft Entra 應用程式。

  4. 在 [管理] 下,選取 [憑證和密碼]

  5. 在 [用戶端祕密] 下,選取 [新增用戶端祕密]

  6. 在 [新增用戶端祕密] 快顯視窗中,提供應用程式祕密的描述、選擇應用程式祕密何時到期,然後選取 [新增]

  7. 從 [用戶端祕密] 區段中,複製新建立的應用程式祕密中 [值] 資料行的字串。 用戶端祕密值是您的「用戶端識別碼」

注意

請務必在用戶端密碼值第一次出現時將其複製。 在瀏覽完此頁面之後,用戶端密碼便會隱藏,您將無法擷取其值。

工作區識別碼

若要取得工作區識別碼 GUID,請遵循下列步驟:

  1. 登入 Power BI 服務。

  2. 開啟您想要內嵌的報表。

  3. 複製 URL 中的 GUID。 GUID 是 /groups//reports/ 之間的數字。

    顯示 Power BI 服務 URL 中工作區識別碼 GUID 的螢幕快照

注意

若要以程式設計方式取得工作區識別碼,請使用取得群組 API。

報表識別碼

若要取得報表識別碼 GUID,請遵循下列步驟:

  1. 登入 Power BI 服務。

  2. 開啟您想要內嵌的報表。

  3. 複製 URL 中的 GUID。 GUID 是 /reports//ReportSection 之間的數字。

    此螢幕擷取畫面顯示 Power BI 服務 URL 中的報表識別碼 GUID

注意

若要以程式設計方式取得報表識別碼,請使用取得群組中的報表 API。

步驟 3 - 新增必要的 NuGet 套件

在可以開始之前,您需要將 Microsoft.Identity.WebMicrosoft.PowerBI.Api NuGet 套件新增至您的應用程式。

將必要的 NuGet 套件新增至您的應用程式:

  • VS Code中,開啟終端機並輸入下列程式碼。

  • Visual Studio 中,瀏覽至 [工具]>[NuGet 套件管理員]>[套件管理員主控台],然後輸入下列程式碼。

dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Identity.Web.UI
dotnet add package Microsoft.PowerBI.Api

步驟 4 - 啟用伺服器端驗證

藉由建立或修改下表中的檔案,在您的應用程式中開啟伺服器端驗證。

檔案 使用
Startup.cs 初始化 Microsoft.Identity.Web 驗證服務
appsettings.json 設定驗證詳細資料
PowerBiServiceApi.cs 取得 Microsoft Entra 權杖和內嵌中繼資料
HomeController.cs 將內嵌資料以模型形式傳遞至檢視

設定您的啟動檔案以支援 Microsoft.Identity.Web

修改 Startup.cs 中的程式碼,以適當地初始化 Microsoft.Identity.Web 所提供的驗證服務。

將下列程式碼新增至應用程式的 Startup.cs 檔案。

注意

ConfigureServices 中的程式碼會完成數個重要事項:

  1. 呼叫 AddMicrosoftWebAppCallsWebApi 會設定 Microsoft 驗證程式庫,以取得存取權杖 (Microsoft Entra 權杖)。
  2. 呼叫 AddInMemoryTokenCaches 會設定權杖快取,而 Microsoft 驗證程式庫將其用來快取存取權杖,並在幕後重新整理這些權杖。
  3. 呼叫 services.AddScoped(typeof(PowerBiServiceApi)) 會將 PowerBiServiceApi 類別設定為服務類別,其可以使用相依性插入新增至其他類別。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using AppOwnsData.Services;

namespace AppOwnsData
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {

    services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
            .EnableTokenAcquisitionToCallDownstreamApi()
            .AddInMemoryTokenCaches();

            services.AddScoped(typeof(PowerBiServiceApi));

            services.AddControllersWithViews(options => {
                var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            });
            services.AddRazorPages()
                    .AddMicrosoftIdentityUI();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You might want to change this for production scenarios. See https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
            });
        }
    }
}

建立驗證詳細資料檔案

在本教學課程中,appsettings.json 檔案包含敏感性資訊,例如「用戶端識別碼」和「用戶端密碼」。 基於安全性原因,我們不建議您將此資訊保留在設定檔中。 在您的應用程式中內嵌時,請考慮更安全的工具 (例如 Azure Key Vault) 以保護敏感性資訊。

  1. 在您的專案中,建立新的檔案並將其命名為 appsettings.json

  2. 將下列程式碼新增至 appsettings.json

    {
     "AzureAd": {
       "Instance": "https://login.microsoftonline.com/",
       "Domain": "yourtenant.onMicrosoft.com",
       "TenantId": "",
       "ClientId": "",
       "ClientSecret": "",
       "CallbackPath": "/signin-oidc",
       "SignedOutCallbackPath": "/signout-callback-oidc"
     },
     "PowerBi": {
       "ServiceRootUrl": "https://api.powerbi.com/"
     },
     "Logging": {
       "LogLevel": {
         "Default": "Information",
         "Microsoft": "Warning",
         "Microsoft.Hosting.Lifetime": "Information"
       }
     },
    "AllowedHosts": "*"
    }
    
  3. 填入從步驟 2 - 取得內嵌參數值中取得的內嵌參數值。

注意

在先前的程式碼中,PowerBi:ServiceRootUrl 參數會新增為自訂設定值,以追蹤 Power BI 服務的基礎 URL。 當您針對 Microsoft 公用雲端中的 Power BI 服務進行程式設計時,URL 是 https://api.powerbi.com/。 不過,Power BI 服務的根 URL 在其他雲端中會有所不同,例如政府雲端。 因此,自定組態值會儲存為專案組態值,因此您可以視需要加以變更。

取得 Microsoft Entra 存取權杖,並呼叫 Power BI 服務

若要內嵌 Power BI 內容 (例如報表和儀表板),您的應用程式必須取得 Microsoft Entra 權杖。 若要取得此權杖,您需要一個設定物件

本節中的程式碼會使用 .NET Core 相依性插入模式。 當您的類別需要使用服務時,您可以針對該服務新增建構函式參數。 .NET Core 執行階段會負責在運行時間傳遞服務執行個體。 在此情況下,建構函式會使用 IConfiguration 參數插入 .NET Core 設定服務的執行個體,用來從 appsettings.json 擷取 PowerBi:ServiceRootUrl 設定值。 ITokenAcquisition 參數 (名為 tokenAcquisition) 會保留對 Microsoft.Identity.Web 程式庫所提供 Microsoft 驗證服務的參考。 ITokenAcquisition 參數可用來從 Microsoft Entra ID 取得存取權杖。

RequiredScopes 欄位會保留字串陣列,其中包含 Power BI 服務 API 支援的一組委派權限。 當您的應用程式透過網路呼叫以取得 Microsoft Entra 權杖時,請傳遞此委派權限集,以便 Microsoft Entra ID 可以將這些權限包含在其傳回的存取權杖中。

注意

驗證您的「Microsoft Entra 應用程式」是否已設定為具有 Web 應用程式所需的範圍。 如需詳細資訊,請參閱變更 Microsoft Entra 應用程式的權限

  1. 在應用程式的專案中,建立標題為 Services 的新資料夾。

  2. Services 資料夾中,建立標題為 PowerBiServiceApi.cs 的新檔案。

  3. 將下列程式碼新增至 PowerBiServiceApi.cs

    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Identity.Web;
    using Microsoft.Rest;
    using Microsoft.PowerBI.Api;
    using Microsoft.PowerBI.Api.Models;
    using Newtonsoft.Json;
    
    namespace AppOwnsData.Services {
    
        // A view model class to pass the data needed to embed a single report
        public class EmbeddedReportViewModel {
            public string Id;
            public string Name;
            public string EmbedUrl;
            public string Token;
        }
    
        public class PowerBiServiceApi {
    
            private ITokenAcquisition tokenAcquisition { get; }
            private string urlPowerBiServiceApiRoot { get; }
    
            public PowerBiServiceApi(IConfiguration configuration, ITokenAcquisition tokenAcquisition) {
                this.urlPowerBiServiceApiRoot = configuration["PowerBi:ServiceRootUrl"];
                this.tokenAcquisition = tokenAcquisition;
            }
    
            public const string powerbiApiDefaultScope = "https://analysis.windows.net/powerbi/api/.default";
    
            // A method to get the Azure AD token (also known as 'access token')
            public string GetAccessToken() {
                return this.tokenAcquisition.GetAccessTokenForAppAsync(powerbiApiDefaultScope).Result;
            }
    
            public PowerBIClient GetPowerBiClient() {
                var tokenCredentials = new TokenCredentials(GetAccessToken(), "Bearer");
                return new PowerBIClient(new Uri(urlPowerBiServiceApiRoot), tokenCredentials);
            }
    
            public async Task<EmbeddedReportViewModel> GetReport(Guid WorkspaceId, Guid ReportId) {
    
                PowerBIClient pbiClient = GetPowerBiClient();
    
                // Call the Power BI service API to get the embedding data.
                var report = await pbiClient.Reports.GetReportInGroupAsync(WorkspaceId, ReportId);
    
                // Generate a read-only embed token for the report.
                var datasetId = report.DatasetId;
                var tokenRequest = new GenerateTokenRequest(TokenAccessLevel.View, datasetId);
                var embedTokenResponse = await pbiClient.Reports.GenerateTokenAsync(WorkspaceId, ReportId, tokenRequest);
                var embedToken = embedTokenResponse.Token;
    
                // Return the report embedded data to caller.
                return new EmbeddedReportViewModel {
                    Id = report.Id.ToString(),
                    EmbedUrl = report.EmbedUrl,
                    Name = report.Name,
                    Token = embedToken
                };
            }
    
        }
    }
    

修改 HomeController.cs 檔案

在此程式代碼範例中,您會使用相依性插入來修改 HomeController.cs 檔案。 依照上一個步驟,您會在 ConfigureServices 方法中呼叫 services.AddScoped,將 PowerBiServiceApi 類別設定為服務。 透過此程式碼,您便可將 PowerBiServiceApi 參數新增至建構函式,而且 .NET Core 執行階段會建立 PowerBiServiceApi 執行個體,並將其傳遞至建構函式。

Controllers 資料夾中,開啟 HomeController.cs 檔案,並將下列程式碼新增至其中:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using AppOwnsData.Models;
using AppOwnsData.Services;

namespace AppOwnsData.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {
        private PowerBiServiceApi powerBiServiceApi;

        public HomeController(PowerBiServiceApi powerBiServiceApi)
        {
            this.powerBiServiceApi = powerBiServiceApi;
        }

        [AllowAnonymous]
        public IActionResult Index()
        {
            return View();
        }

        public async Task<IActionResult> Embed() {

            // Replace these two GUIDs with the workspace ID and report ID you recorded earlier.
            Guid workspaceId = new Guid("11111111-1111-1111-1111-111111111111");
            Guid reportId = new Guid("22222222-2222-2222-2222-222222222222");

            var viewModel = await powerBiServiceApi.GetReport(workspaceId, reportId);

            return View(viewModel);
        }

        [AllowAnonymous]
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

步驟 5 - 建置應用程式的用戶端

針對用戶端實作,您需要建立或修改下表中列出的檔案:

檔案 使用
embed.js 包含用戶端 JavaScript 程式碼
Embed.cshtml 包含應用程式的文件物件模型 (DOM),以及用於內嵌報表的 DIV

為內嵌的報表建立容器

在此教學課程中,您會建立 Embed.cshtml 檔案,其中具有一個 div 元素 (用作內嵌報表的容器) 和三個指令碼。

  1. View/Home 資料夾中,建立稱為 Embed.cshtml 的檔案。

  2. 將下列程式碼新增至 Embed.cshtml 檔案。

    @model AppOwnsData.Services.EmbeddedReportViewModel;
    
    <div id="embed-container" style="height:800px;"></div>
    
    @section Scripts {
    
        <!-- powerbi.min.js is the JavaScript file that loads the client-side Power BI JavaScript API library.
        Make sure that you're working with the latest library version.
        You can check the latest library available in https://cdnjs.com/libraries/powerbi-client -->
        <script src="https://cdn.jsdelivr.net/npm/powerbi-client@2.18.0/dist/powerbi.min.js"></script>
    
        <!-- This script creates a JavaScript object named viewModel which is accessible to the JavaScript code in embed.js. -->
        <script> 
            var viewModel = {
                reportId: "@Model.Id",
                embedUrl: "@Model.EmbedUrl",
                token: "@Model.Token"
            }; 
        </script>
    
        <!-- This script specifies the location of the embed.js file -->
        <script src="~/js/embed.js"></script>
    }
    

新增用戶端 JavaScript 以內嵌報表

若要內嵌 Power BI 內容,您必須建立一個設定物件。 若要深入了解如何建立設定物件,請參閱內嵌報表

在本教學課程中,您會使用變數 models 建立名為 embed.js 的 JavaScript 檔案,其中具有一個用於內嵌報表的設定物件。

您可以使用 window['powerbi-client'].models 呼叫來初始化 modelsmodels 變數用來設定 models.Permissions.Allmodels.TokenType.Aadmodels.ViewMode.View 等設定值。

powerbi.embed 函式會使用 models 設定物件來內嵌您的報表。

  1. wwwroot/js 資料夾中,建立稱為 embed.js 的檔案。

  2. 將下列程式碼新增至 embed.js 檔案。

    $(function () {
    
        // 1 - Get DOM object for the div that's the report container.
        var reportContainer = document.getElementById("embed-container");
    
        // 2 - Get the report embedding data from the view model.
        var reportId = window.viewModel.reportId;
        var embedUrl = window.viewModel.embedUrl;
        var token = window.viewModel.token
    
        // 3 - Embed the report by using the Power BI JavaScript API.
        var models = window['powerbi-client'].models;
    
        var config = {
          type: 'report',
          id: reportId,
          embedUrl: embedUrl,
          accessToken: token,
          permissions: models.Permissions.All,
          tokenType: models.TokenType.Embed,
          viewMode: models.ViewMode.View,
          settings: {
            panes: {
              filters: { expanded: false, visible: true },
              pageNavigation: { visible: false }
            }
          }
        };
    
        // Embed the report and display it within the div container.
        var report = powerbi.embed(reportContainer, config);
    
        // 4 - Add logic to resize the embed container on a window resize event.
        var heightBuffer = 12;
        var newHeight = $(window).height() - ($("header").height() + heightBuffer);
        $("#embed-container").height(newHeight);
        $(window).resize(function () {
          var newHeight = $(window).height() - ($("header").height() + heightBuffer);
          $("#embed-container").height(newHeight);
        });
    
      });
    

步驟 6 - 執行您的應用程式

遵循所有先前步驟之後,您就可以開始執行應用程式。 嘗試執行您的應用程式,並實驗 Power BI 報表的內嵌方式。 您可以使用 Power BI 內嵌式分析用戶端 API,透過用戶端 API 增強您的應用程式。

重要

如果您使用免費內嵌試用權杖進行開發,則必須購買生產容量。 購買容量之前,免費試用版本橫幅將持續出現在內嵌報表頂端。

當您的應用程式備妥時,您可以將內嵌應用程式移至實際執行環境