Power BI Embedded using Web Forms and Row Level Security

If you are looking for a way to spice up your old Web Form application, consider adding the power of Power BI embedded. Today I will show you the specific steps needed to add a Power BI Report to a custom Web Forms application using the Microsoft Power BI Embedded Service. This blog is a follow up to my Row Level Security with Power BI Embedded using MVC blog as the Power BI Report, row level security and Azure setup is the exact same.

Please refer to the Row Level Security with Power BI Embedded using MVC blog post for the non web form specific steps.

Before you start, you will need a number of items.
1) A Power BI report created using Direct Query
2) A subscription to Microsoft Azure
3) Microsoft’s Provision Sample application
4) A web form application in Visual Studio
5) The appropriate NuGet packages
6) Read the MVC blog post before going further

Azure Power BI Embedded service and Web Forms.

Microsoft provides a sample Web Form application via Mostafa Elzoghbi and Channel 9 at Power BI Embedded Explained – Part 4. This video is where I started and is a useful refresher as you start your Web Form application.

Just like the MVC application, first you need to provide the Azure information you collected to your application. With your reports uploaded to Azure you will also need to use the Microsoft sample application or create a custom call in your application to get your Report IDs, this can be done via Reports.GetReports from the IPowerBIClient interface. Once you have the needed Report IDs you can store them along with the rest of your Azure information via a database or the Webconfig, the webconfig method is show below.

Don’t forget to add your NuGet packages, just like the MVC application you will need those:

Install-Package Microsoft.PowerBI.Core 
Install-Package Microsoft.PowerBI.API 
Install-Package Microsoft.PowerBI.JavaScript 
Install-Package Newtonsoft.Json 
Install-Package Microsoft.Rest.ClientRuntime

 

Web.config

<span class="hljs-tag"><<span class="hljs-name">appSettings</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">add</span> <span class="hljs-attr">key</span>=<span class="hljs-string">"powerbi:AccessKey"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span> /></span> //One of your two access keys
    <span class="hljs-tag"><<span class="hljs-name">add</span> <span class="hljs-attr">key</span>=<span class="hljs-string">"powerbi:ApiUrl"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"https://api.powerbi.com"</span> /></span>
    <span class="hljs-tag"><<span class="hljs-name">add</span> <span class="hljs-attr">key</span>=<span class="hljs-string">"powerbi:WorkspaceCollection"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span> /></span> //Workspace collection name
    <span class="hljs-tag"><<span class="hljs-name">add</span> <span class="hljs-attr">key</span>=<span class="hljs-string">"powerbi:WorkspaceId"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span> /></span> //Workspace id
    <span class="hljs-tag"><<span class="hljs-name">add</span> <span class="hljs-attr">key</span>=<span class="hljs-string">"powerbi:ReportMain"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span> /></span> //Report id one
    <span class="hljs-tag"><<span class="hljs-name">add</span> <span class="hljs-attr">key</span>=<span class="hljs-string">"powerbi:ReportRole"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span> /></span> //Report id two
<span class="hljs-tag"></<span class="hljs-name">appSettings</span>></span>

 

It is possible to store all the logic for your reports in a single aspx page and code behind or you can create a set of pages for each report. Either way you will need to create a PowerBI object via the IPowerBIClient interface and use the Page_Load method to control adding the report to the page.

First, setup your page to accept the Power BI report by adding two hidden inputs, an iframe and a javascript function:

<span class="hljs-tag"><<span class="hljs-name">asp:Content</span> <span class="hljs-attr">ID</span>=<span class="hljs-string">"BodyContent"</span> <span class="hljs-attr">ContentPlaceHolderID</span>=<span class="hljs-string">"MainContent"</span> <span class="hljs-attr">runat</span>=<span class="hljs-string">"server"</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">h2</span>></span><span class="hljs-tag"><<span class="hljs-name">%:</span> <span class="hljs-attr">Title</span> %></span>.<span class="hljs-tag"></<span class="hljs-name">h2</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"hidden"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"accessTokenText"</span> <span class="hljs-attr">runat</span>=<span class="hljs-string">"server"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span> /></span>
    <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"hidden"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"embedUrlText"</span> <span class="hljs-attr">runat</span>=<span class="hljs-string">"server"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span> /></span>

    <span class="hljs-tag"><<span class="hljs-name">iframe</span> <span class="hljs-attr">ID</span>=<span class="hljs-string">"iFrameEmbedReport"</span>  <span class="hljs-attr">height</span>=<span class="hljs-string">"768"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"1024"</span> <span class="hljs-attr">seamless</span>></span><span class="hljs-tag"></<span class="hljs-name">iframe</span>></span> 

    <span class="hljs-comment"><!-- Js function to assign iframe embedUrl and access token --></span>
    <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span>></span><span class="javascript">

         <span class="hljs-built_in">window</span>.onload = <span class="hljs-function"><span class="hljs-keyword">function</span> ()
            </span>{ <span class="hljs-comment">// find the iFrame on the page and handle the loaded event.</span>
              <span class="hljs-keyword">var</span> iframe = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'iFrameEmbedReport'</span>);
              iframe.src = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'MainContent_embedUrlText'</span>).value;  <span class="hljs-comment">//embedReportUrl;</span>
              iframe.onload = postActionLoadReport;
              <span class="hljs-comment">// post the access token to the iFrame to load the tile</span>
              <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">postActionLoadReport</span>() </span>{
                  <span class="hljs-comment">// get the app token.</span>
                  accessToken = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'MainContent_accessTokenText'</span>).value;<span class="hljs-comment">//{generate app token};</span>
                  <span class="hljs-comment">// construct the push message structure</span>
                  <span class="hljs-keyword">var</span> m = { <span class="hljs-attr">action</span>: <span class="hljs-string">"loadReport"</span>, <span class="hljs-attr">accessToken</span>: accessToken };
                  message = <span class="hljs-built_in">JSON</span>.stringify(m);
                  <span class="hljs-comment">// push the message.</span>
                  iframe = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'iFrameEmbedReport'</span>);
                  iframe.contentWindow.postMessage(message, <span class="hljs-string">"*"</span>);
                  }
              };
    </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"></<span class="hljs-name">asp:Content</span>></span>

 

Then make sure your code behind has the following using directives:

using System;
using System.Collections.Generic;
using System.Web.UI;
using Microsoft.PowerBI.Api.V1;
using Microsoft.PowerBI.Security;
using System.Configuration;
using Microsoft.Rest;

Now add the following code to your page’s class:

        private static string ReportID = ConfigurationManager.AppSettings["powerbi:ReportRole"];
        private static string workspaceCollection = ConfigurationManager.AppSettings["powerbi:WorkspaceCollection"];
        private static string workspaceId = ConfigurationManager.AppSettings["powerbi:WorkspaceId"];
        private static string accessKey = ConfigurationManager.AppSettings["powerbi:AccessKey"];
        private static string apiUrl = ConfigurationManager.AppSettings["powerbi:ApiUrl"];

        private IPowerBIClient CreatePowerBIClient()
        { 
            var credentials = new TokenCredentials(accessKey, "AppKey");

            var client = new PowerBIClient(credentials)

            {

                BaseUri = new Uri(apiUrl)

            };

            return client;
        }
        protected void Page_Load(object sender, EventArgs e)
        {

            if (!Page.IsPostBack)
            {

                using (var client = this.CreatePowerBIClient())
                {

                    string myUserID = User.Identity.Name.ToString();
                    IEnumerable<span class="hljs-tag"><<span class="hljs-name">string</span>></span> myRole = new List<span class="hljs-tag"><<span class="hljs-name">string</span>></span>() { "Customer", "Developer" };
                    var embedToken = (myUserID == "") ? PowerBIToken.CreateReportEmbedToken(workspaceCollection, workspaceId, ReportID) : PowerBIToken.CreateReportEmbedToken(workspaceCollection, workspaceId, ReportID, myUserID, myRole);
                    string myTok = embedToken.Generate(accessKey);

                    accessTokenText.Value = myTok;  //input on the report page.

                    embedUrlText.Value = "https://embedded.powerbi.com/appTokenReportEmbed?reportId=" + ReportID; //input on the report page.

                }
            }
        }

That is it, call your page and your embedded report should load.

Jamie Mikami

Jamie Mikami

Jamie Mikami is a VP of Application Development, an experienced solutions architect who has spent over 25 years conceptualizing, optimizing, and successfully implementing information technology projects. A specialist in Microsoft products and data solutions, Jamie builds collaborative environments and constantly mentors his team on technology systems to bring more opportunity for growth and innovation.
SHARE THIS
Share on twitter
Share on facebook
Share on linkedin
Share on email
RELATED POSTS
Stay Connected

Subscribe to CSG Pro. We’ll supply your inbox with the latest blog posts, training videos, and upcoming events.

Search

Ready to wrangle your data?