Is there any way to embed power bi reports and dashboards in vb.net or C# desktop application with sql server 2008 database?

Yes, absolutely! As @David Browne said in his response, it’s just a matter of loading something in a web browser. Generally, it doesn’t matter what are your data sources – SQL Server or flat files, it’s all the same. You can see how it looks like in Power BI Embedded Playground.

You have two ways to embed Power BI reports (or dashboards or tiles, it’s essentially the same):

  1. Use Power BI Report Server installed on premise. To embed a report, just add an iframe into a web page and set it’s source to report’s URL, but add ?rs:embed=true to it. However, Power BI Reporting Server is quite expensive. You need a license for SQL Server Enterprise with software assurance, or Power BI Premium subscriptions. Advantage in this case could be the fact, that the data is kept on premise, because in some cases publishing data to the cloud could be disallowed or difficult to certify and guarantee data privacy.

  2. Publish you reports to Power BI Service (i.e. online to Power BI web site). The advantage of this scenario is its price. You can implement solutions with single Power BI Pro account, i.e. $10 per month. The disadvantage could be that your data must be accessible for Power BI Service (i.e. outside of your internal network) and it’s a bit more complex to embed.

When you embed Power BI into your application, there are two scenarios to choose from – user owns data and app owns data. With the first one each user needs its own Power BI Pro account and uses it to see the embedded report. With the second scenario you need only one “master” Power BI Pro account (it’s also possible to embed it authenticating with service principal, but let’s keep it simple for now).

You didn’t mention is you vb.net application web app or desktop. Here is a very nice demo how to embed Power BI into WPF application and here are Microsoft’s official samples how to do this in a web app.

I will explain in more details how to embed it in a desktop application, but with web apps essentially is the same.

First you need to publish your report to Power BI Service. It will be better to use a dedicated workspace for this. Make sure the Pro account, which you will use as “master” account in your app, has rights for this workspace. It’s not a good idea to use your (probably admin) account, because it has way more privileges than needed. You can, but if $10/month are not an issue, then spent them for a dedicated account (or use service principal).

Then you need to register an application. Enter some descriptive app name, set application type to be Native app. Select the permissions that will be required for your application, i.e. if if will only read data, don’t grant “read and write” permissions to it. Or grant them all. It’s your decision. Register the application and copy the guid that you will get. It is called “app id” or “client id”. You will need it later.

The next step is to authenticate your app against Azure AD. Use Azure Active Directory Authentication Libraries (ADAL) for this. Add ADAL to your progect (e.g. using NuGet) and use following code to acquire an access token (the code is in C#, because I didn’t wrote in vb for many years, but you should have no problems translating it), but assign the guid that you got to clientId and provide values for masterAccountName and masterAccountPassword:

using Microsoft.IdentityModel.Clients.ActiveDirectory;

private static string redirectUri = "https://login.live.com/oauth20_desktop.srf";
private static string resourceUri = "https://analysis.windows.net/powerbi/api";
private static string authorityUri = "https://login.windows.net/common/oauth2/authorize";
private static string clientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

private static AuthenticationContext authContext = new AuthenticationContext(authorityUri, new TokenCache());

// First check is there token in the cache
try
{
    authenticationResult = authContext.AcquireTokenSilentAsync(resourceUri, clientId).Result;
}
catch (AggregateException ex)
{
    AdalException ex2 = ex.InnerException as AdalException;
    if ((ex2 == null) || (ex2 != null && ex2.ErrorCode != "failed_to_acquire_token_silently"))
    {
        throw new ApplicationException(ex.Message);
    }
}

if (authenticationResult == null)
{
    var uc = new UserPasswordCredential(masterAccountName, masterAccountPassword);
    authenticationResult = authContext.AcquireTokenAsync(resourceUri, clientId, uc).Result;
}

At the end authenticationResult.AccessToken will contain the access token that you will need. If you are curious what is inside it, go to https://jwt.io/ and paste it to get it decoded.

Call Get Report In Group Power BI REST API to get report’s embedUrl. Use code like this (it uses Newtonsoft.Json), providing actual groupId (workspaceId), reportId (you can get them from the URL of your report, when it is shown in a web browser) and accessToken:

string powerBIDatasetsApiUrl = $"https://api.powerbi.com/v1.0/myorg/groups/{groupId}/reports/{reportId}";

var request = WebRequest.Create(powerBIDatasetsApiUrl) as HttpWebRequest;
request.KeepAlive = true;
request.Method = "GET";
request.ContentLength = 0;
request.ContentType = "application/json";

request.Headers.Add("Authorization", $"Bearer {accessToken}");

using (HttpWebResponse httpResponse = request.GetResponse() as System.Net.HttpWebResponse)
{
    using (StreamReader reader = new System.IO.StreamReader(httpResponse.GetResponseStream()))
    {
        string responseContent = reader.ReadToEnd();
        var responseJson = JsonConvert.DeserializeObject<dynamic>(responseContent);
        return responseJson["embedUrl"];
    }
}

Here comes the tricky part. You need Power BI JavaScript client to use the url that you get with the code above. The easiest way is to get ReportLoader.html, ReportLoader.js and powerbi.js from the WPF sample above. You can read in details about these files here, but in general the HTML file contains an empty <div>, where the report will be loaded, and you call code in ReportLoader.js, passing some parameters (which report, access token, access token type, etc.), and it will call the Power BI JavaScript client to do the heavy lifting for you.

The parameters, that you will pass to the loader code, with code like this:

var parameters = new object[] { embedUrl, accessToken, reportId, "report" /* or "dashboard" or "tile"*/, 0 /* 0 - AAD, 1 - Embed */, string.Empty };
webBrowser.Document.InvokeScript("LoadEmbeddedObject", parameters);

webBrowser is a web browser component, in which you load ReportLoader.html. embedUrl and accessToken are the values, that you acquired before, the ID of the report, embed element type (is it report, tile or dashboard), access token type (is it AAD, which we used in this case, or embed) and for now leave the last one empty (for more details about that see Embed Configuration Details). The difference between AAD and Embed tokens is that embed tokens are valid for particular element (e.g. report), while AAD tokens can be used to authenticate yourself in many different calls. This means that it’s safer to use embed tokens, because they can be used only to embed this particular report and can’t be used to perform other REST API calls. Keep in mind, that this access token is visible at client side (it’s in the JavaScript code). If you want to use embed tokens, then use the AAD token at server side to call GenerateTokenInGroup, but this require a dedicated capacity assigned to this workspace (i.e. Power BI Premium or Power BI Embedded) and without a capacity, your Pro account has limited number of tokens, which you can use for development only.

After that, your report should be successfully loaded into webBrowser.

I will also recommend you to watch this video Using App-only Authentication with Power BI Embedding with Ted Pattison.

Leave a Comment