Embedding Power BI Report into .NET Core | Angular JS application with app owned data

While working on .NET Core application with Angular JS, I came across a requirement of embedding Power BI report in my application. Following Nuget packages are available for embedding Power BI report, but these packages are compatible with ASP.NET MVC and not compatible with .NET Core

  1. Microsoft.PowerBI.Api
  2. Microsoft.PowerBI.AspNet.Mvc
  3. Microsoft.PowerBI.Core

So one way of doing this would be to use REST APIs. Let’s see what all steps are required

  1. Get OAuth access token from Azure Active Directory (using OAuth 2.0 endpoint)
  2. Get Power BI report details (using Power BI REST API, version 1.0)
  3. Get Power BI report embed token (Power BI REST API, version 1.0)
  4. Embed report using Microsoft.PowerBI.JavaScript

Let’s see the configuration required before working on code changes.

Register App in Azure Active Directory

1. Navigate to Azure Active Directory from left pane and click App registrations and click New application registration

2. Enter application registration information on Create window

Name: Application name
Application type: Select Native option.
Redirect URI:  Provide the URI used by Azure to return token response

3. Click Create button.

4. Click on the newly created app to set permissions. Click on the Settings button

5. Click on Required permissions on Settings pane

6. Click on Add button

7. Click on Select an API

8. Select Power BI Service (Power BI)

9. Select all permissions under DELEGATED PERMISSIONS

10. Click on Select button and click Grant Permissions (as an administrator, consent to application’s delegated permissions on behalf of all users in the tenant)

Code changes

1. Define models

Let’s define models first to deserialize response from REST APIs

1. 1. AzureAdTokenResponse – Deserialize response from get access token API


   public class AzureAdTokenResponse
   {
      [JsonProperty("access_token")]
      public string AccessToken { get; set; }
   }

1.2. PowerBiReport – Deserialize response from get Power BI report details API


   public class PowerBiReport
   {
      [JsonProperty(PropertyName = "id")]
      public string Id { get; set; }

      [JsonProperty(PropertyName = "name")]
      public string Name { get; set; }

      [JsonProperty(PropertyName = "webUrl")]
      public string WebUrl { get; set; }

      [JsonProperty(PropertyName = "embedUrl")]
      public string EmbedUrl { get; set; }

      [JsonProperty(PropertyName = "datasetId")]
      public string DatasetId { get; set; }
   }

1.3. PowerBiEmbedToken – Deserialize response from get Power BI report embed token


   public class PowerBiEmbedToken
   {
      [JsonProperty(PropertyName = "token")]
      public string Token { get; set; }

      [JsonProperty(PropertyName = "tokenId")]
      public string TokenId { get; set; }

      [JsonProperty(PropertyName = "expiration")]
      public DateTime? Expiration { get; set; }
   }

2. Code to get embed token and URL

Let’s create a controller and add action method for getting embed token and URL. This action method would be invoked by Angular JS script on click of a button. The controller action code looks like following.

Note: Replace placeholders (formatted with bold and italic style) with actual values in the code below


   // Step 1: Get Access Token
   HttpClient client = new HttpClient();

   var content = new FormUrlEncodedContent(new[]
   {
      new KeyValuePair<string, string>("grant_type", "password"),
      new KeyValuePair<string, string>("username", "<username>"]),
      new KeyValuePair<string, string>("password", "<password>"]),
      new KeyValuePair<string, string>("client_id", "<clientId>"]),
      new KeyValuePair<string, string>("scope", "openid"),
      new KeyValuePair<string, string>("resource", "https://analysis.windows.net/powerbi/api")
   });

   string accessToken = 
await client.PostAsync("https://login.microsoftonline.com/<tenantName>/oauth2/token", content)
   .ContinueWith<string>((response) =>
   {
      AzureAdTokenResponse tokenRes =
      JsonConvert.DeserializeObject<AzureAdTokenResponse>(response.Result.Content.ReadAsStringAsync()
.Result);
      return tokenRes?.AccessToken;
   });

   // Step 2: Get Report details
   // Pass on the access token received from previous step
   HttpClient client = new HttpClient();
   client.DefaultRequestHeaders.Add("Authorization", $"Bearer <accessToken>");

   reportJson = 
await client.GetAsync("https://api.powerbi.com/v1.0/myorg/groups/<groupid>/reports/<reportid>", content)
   .ContinueWith<string>((response) => response.Result.Content.ReadAsStringAsync().Result);

   PowerBiReport report = 
JsonConvert.DeserializeObject<PowerBiReport>(((ContentResult)result.Result).Content);

   // Step 3: Get Embed Token
   // Pass on the access token received from previous step
   HttpClient client = new HttpClient();
   client.DefaultRequestHeaders.Add("Authorization", $"Bearer <accessToken>");

   var content = new FormUrlEncodedContent(new[]
   {
      new KeyValuePair<string, string>("accessLevel", "view")
   });

   var embedToken = await 
client.PostAsync("https://api.powerbi.com/v1.0/myorg/groups/<groupid>/reports/<reportid>/GenerateToken"
          , content)
   .ContinueWith<string>((response) => response.Result.Content.ReadAsStringAsync().Result);

   // Step 4: Return token details
   return new {
      EmbedToken = embedToken,
      EmbedUrl = report.EmbedUrl,
      Id = report.Id
   }

3. Import Nuget Package

Now import following Nuget package for integrating Power BI report into the page via JavaScript

  • Import Nuget package Microsoft.PowerBI.JavaScript
  • Include powerbi.js in the project

4. Html

Add following html control which would work as a container for power BI report when embedded. Also add a button and invoke the controller action (mentioned in the code above) to get embed token and URL.


   <div id="reportContainer"></div>
   <button ng-click="getEmbedToken()">Show Report</button>

5. JavaScript

1. Get Embed Token and URL (getEmbedToken method) by calling controller action defined in the code above
2. Add following code and invoke powerbi functions from powerbi.js to embed power BI report. Use accessToken, embedUrl, embedReportId while preparing embed configuration


   var models = window['powerbi-client'].models;

   var config = {
      type: 'report',
      tokenType: models.TokenType.Embed,
      accessToken: accessToken,
      embedUrl: embedUrl,
      id: embedReportId,
      permissions: models.Permissions.All,
      settings: {
         filterPaneEnabled: false,
         navContentPaneEnabled: true
      }
   };

   // Get a reference to the embedded report HTML element
   var reportContainer = $('#reportContainer')[0];

   // Embed the report and display it within the div container.
   var report = powerbi.embed(reportContainer, config);

6. Execute the code to see the Power BI report embedded into the application !!

References