Lors de la réalisation d’un nouveau projet, de plus en plus de clients souhaitent obtenir des statistiques, des indicateurs de performance (KPI en anglais), liés à leur nouvelle application. Une manière élégante de présenter ces données passe par un affichage graphique, soit en concevant soit même les diagrammes avec des bibliothèques Javascript comme D3.js ou ChartJS, ce qui peut prendre un temps considérable lorsque l’on n’est pas initié à ces librairies, soit en utilisant Power Bi. Ces rapports peuvent ensuite être partagés en via des fichiers, via l’application en ligne Power Bi, ou mieux encore : directement dans l’application pour laquelle le(s) rapport(s) Power Bi ont été conçus.

L’objectif de cet article est de présenter l’intégration d’un rapport Power Bi (on utilise le terme Power Bi Embedded en anglais pour ce type d’opération) dans une application ASP.NET Core.

Prérequis :

  • Avoir un compte dans l’Azure Active Directory dans le locataire (tenant) où sera hébergé le rapport Power Bi ;
  • Avoir une licence Power Bi Pro associée à votre compte (une version d’essai gratuite limitée à 60 jours est disponible pour Power Bi Pro).
  • Être administrateur sur Azure ou pouvoir obtenir des droits de la part d’un administrateur sur Azure

Hébergement du rapport dans Power Bi Online

Prérequis :

  • Une licence Power Bi Pro est indispensable pour se connecter à Power Bi Online.

La première étape indispensable est d’héberger votre rapport dans Power Bi en ligne. J’ai tout d’abord créé un rapport de test en local avec l’application lourde Power Bi Destkop.

Une fois terminé, je me rends sur https://app.powerbi.com/ pour créer un espace de travail dédié à ce rapport, en cliquant sur « Espaces de travail » dans le menu gauche, puis « Créer un espace de travail » en bas du nouveau menu apparu.

Formulaire de création d’un espace de travail Power Bi

Formulaire de création d’un espace de travail Power Bi

Après avoir renseigné les informations requises et enregistrer mon nouvel espace de travail, celui-ci apparaît dans le menu gauche. Vous pouvez également le retrouvez en cliquant sur « Espaces de travail », qui ouvre un menu listant tous vos espaces de travail. Votre workspace étant vide, la page ci-dessous s’affiche quand vous y accédez.

Écran affiché à la création d’un nouvel espace de travail

Nous allons ensuite charger le rapport que vous avez créé dans Power Bi Desktop en cliquant sur « Obtenir » dans la case « Fichiers » (troisième tuile blanche). Vous êtes redirigés sur une nouvelle page vous demandant votre moyen d’import. Choisissez « Fichier local » puis sélectionnez le fichier .pbix que vous avez conçu via Power Bi Desktop.

Écran de chargement du rapport Power Bi

Maintenant que nous avons importé ce fichier dans Power Bi Online, il est temps de l’intégrer dans votre application. Deux solutions s’offrent à vous :

  • L’intégration par une iFrame
  • La récupération du rapport en C# et en JavaScript

Intégration via une iFrame

Cette solution est de loin la plus simple et la plus rapide à mettre en place. Pour se faire, sélectionnez votre rapport dans Power Bi Online.

Rapport importé dans Power Bi Online

Une fois sur celui-ci, choisissez « Fichiers > Incorporer », et récupérer le code iFrame dans la fenêtre qui s’affiche. Une fois ce code copié, collez le dans la vue de votre choix de votre projet.

Code iFrame inséré dans une vue de notre projet

L’affichage du rapport par l’iFrame n’est possible que si l’utilisateur dispose d’un compte dans l’Azure AD. Si l’utilisateur est déjà connecté, l’affichage du rapport s’effectue instantanément. Sinon, un bouton est affiché pour permettre à l’utilisateur de s’authentifier : après clic dessus, il est redirigé vers la page de connexion dans un nouvel onglet, et le rapport s’affiche une fois l’authentification réussie.

Demande d’autorisation pour un rapport affiché par iFrame si l’utilisateur n’est pas connecté

Intégration en C# et JavaScript

L’autre méthode de récupération consiste à utiliser différentes librairies pour collecter le rapport et l’afficher aux utilisateurs

L’exemple d’intégration suivant est réalisé dans un projet MVC avec le framework .Net Core version 3.1.3, avec une authentification simple/à un facteur sur Azure (la méthode de récupération du token utilisée ci-après n’est pas compatible avec une authentification multi-facteur). La récupération du token d’accès et du rapport se fait dans mon HomeController, et l’affichage dans la page d’accueil (Index.cshtml).

Enregistrer l’application

Tout d’abord, il faut enregistrer l’application. Deux solutions possibles :

Dans le premier cas, il faudra tout d’abord vous connecter avec votre compte Azure AD (attention à bien avoir une licence Power Bi Pro), puis renseignez tous les champs du formulaire. Dans le cas de mon exemple, je renseigne l’adresse locale pour ce test. Pour ce qui est des droits, j’ai tout sélectionné, libre à vous de choisir ceux qui sont requis et ceux qui ne le sont pas.

Comme il s’agit de l’enregistrement d’une nouvelle application, votre compte doit être administrateur dans l’Azure AD pour éviter tout problème à la création.

Note : Pour un premier test, je vous conseille de tout sélectionner et de décocher ultérieurement ce qui n’est pas nécessaire.

Enregistrement de l’application via le site https://dev.powerbi.com/apps

Une fois votre application créée, l’applicationId et l’applicationSecret sont affichés et vous pouvez les récupérer et les conserver.

La seconde solution d’enregistrement se fait directement par le portail Azure. Personnellement c’est celle que je préfère. Il faut créer une nouvelle application par le menu gauche « Tous les services » puis « Inscriptions d’applications ».

Accès à la page d’enregistrement d’une nouvelle application via Azure (interface en anglais)

Une fois l’application créée, il faut ajouter les autorisations pour Power Bi Service dans la page « API Autorisées ». Une fois les autorisations ajoutées, n’oubliez pas d’accorder le consentement d’administrateur en cliquant sur le bouton en haut de la page (vous ne pouvez accorder le consentement qu’en étant administrateur).

Ajout des autorisations Power Bi pour l’application dans l’interface Azure

Vous pouvez récupérer l’applicationId dans l’URL de la page de l’application, et l’applicationSecret via le menu « Certificats & secrets ».

Installer les packages nécessaires

Côté C#, installez le nugget suivant : Microsoft.PowerBi.Api.

Note : vous trouverez peut-être dans d’autres tutoriels des avis recommandant d’utiliser la version 2 et non la version 3 car cette dernière pouvait poser des problèmes. J’ai donc testé avec les deux versions (2.14.0 et 3.11.1), et hormis quelques adaptations de code à faire, je n’ai rencontré aucun problème.

Pour la partie JavaScript, il faut installer PowerBi-JavaScript (que vous trouverez aussi appelé powerbi-client) : https://github.com/microsoft/PowerBI-JavaScript

Pour ma part, j’utilise le gestionnaire de bibliothèques côté client dans Visual Studio pour installer ce package. Je passe par le fournisseur unpkg pour charger ma library. Attention, le fournisseur ne propose pas de complétion lors de recherche de bibliothèque, il faut saisir l’intégralité du nom combiné la version (formalisme nom@numeroVersion) pour que les fichiers correspondants soient trouvés. Vous pouvez trouver la dernière version dans un moteur de recherche en écrivant « unpkg nomDeLaLibrary ».

Installation de powerbi-client par le gestionnaire de bibliothèques côté client dans Visual Studio

Mettre à jour l’appSettings

Renseignez dans votre appsettings.json les différentes informations liées à votre rapport et votre application Power Bi.

"PowerBi": {
    "TenantId": "bcf00c7e-1bd4-XXXX-XXXX-XXXXXXXXXXXX",
    "ApplicationId": "8f4424b3-5387-XXXX-XXXX-XXXXXXXXXXXX",
    "ApplicationSecret": "NLao**********",
    "ResourceUri": "https://analysis.windows.net/powerbi/api",
    "LicenceUsername": "alexandre.levacher@devolis.com",
    "LicencePassword": "**********",
    "GroupId": "d0d48f16-0bb5-XXXX-XXXX-XXXXXXXXXXXX",
    "ReportId": "2998793e-c68e-XXXX-XXXX-XXXXXXXXXXXX"
  }

 

En reprenant l’extrait de code ci-dessous, les informations à définir sont :

  • L’ID du locataire (tenant)
  • L’ID et la clé secrète de l’application que vous avez enregistrée dans Azure
  • Le compte utilisateur (login et mot de passe) pour accéder au rapport. Ce compte doit être titulaire d’une licence Power Bi Pro.
  • Les ID du groupe et du rapport, récupérés depuis le lien d’accès du rapport de Power Bi Online (voir image ci-après). Normalement, il est possible de récupérer un rapport simplement avec l’ID du rapport, mais je préfère récupérer cette information par le groupe. Vous pourrez également trouver dans d’autres tutoriels des personnes qui passent non pas par le GroupId mais par le WorkspaceId pour récupérer le rapport.

Récupération du GroupId (rouge) et ReportId (vert) depuis Power Bi Online

Code à ajouter dans le Controller

Dans le HomeController, je définis une méthode GetPowerBi() que j’appellerai dans ma vue en Ajax. Cette méthode fait deux choses : tout d’abord elle récupère un token d’accès valide pour permettre l’authentification, via une autre méthode GetAccessToken(), puis elle obtient ce rapport en utilisant le token précédemment obtenu.

private async Task<string> GetAccessToken()
{
    using (HttpClient client = new HttpClient())
    {
        string tenantId = _configuration["PowerBi:TenantId"];
        var tokenEndpoint = $"https://login.microsoftonline.com/{tenantId}/oauth2/token";
        var userName = _configuration["PowerBi:LicenceUsername"];
        var password = _configuration["PowerBi:LicencePassword"];
        var clientId = _configuration["PowerBi:ApplicationId"]; ;
        var clientSecret = _configuration["PowerBi:ApplicationSecret"];

        client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded");
            string postBody = null;

        postBody = $@"resource={_configuration["PowerBi:ResourceUri"]}&client_id={clientId}&client_secret={clientSecret}&grant_type=password&username={userName}&password={password}&score=openid";

        var stringContent = new StringContent(postBody, Encoding.UTF8, "application/x-www-form-urlencoded");

        var result = await client.PostAsync(tokenEndpoint, stringContent).ContinueWith<string>((response) =>
        {
            return response.Result.Content.ReadAsStringAsync().Result;
        });

        JObject jobject = JObject.Parse(result);

        return jobject["access_token"].Value<string>();
    }
}

Dans cet exemple, j’utilise mon login et mot de passe renseigné dans l’appsettings. Cependant, dans le cadre d’une application où les utilisateurs sont connectés avec l’Azure AD, vous pouvez récupérer leurs identifiants pour récupérer ensuite le token d’accès (licence Power Bi Pro nécessaire).

Attention : cette méthode de récupération de token n’est pas possible si le multi-factor authentication est activé (vous aurez une erreur AADSTS50076).

Une fois le token récupéré, en récupère le rapport Power Bi grâce aux ID renseignés dans l’appsettings. Plusieurs méthodes de récupération sont possibles ce qui offre un grand panel de possibilité, par exemple certaines permettent de récupérer tous les rapports d’un groupe ce qui peut être pratique. Dans mon exemple, je récupère un rapport précis dans un groupe spécifique.

public async Task<IActionResult> GetPowerBi()
{
    try
    {
        var accessToken = await GetAccessToken();
        var tokenCredentials = new TokenCredentials(accessToken, "Bearer");
        using (var client = new PowerBIClient(new Uri("https://api.powerbi.com/"), tokenCredentials))
        {
            var groupIdGuid = new Guid(_configuration["PowerBi:GroupId"]);
            var reportIdGuid = new Guid(_configuration["PowerBi:ReportId"]);
            var reportPrecis = client.Reports.GetReportInGroup(groupIdGuid, reportIdGuid);
            return Json(new { success = true, accessToken = accessToken, report = reportPrecis });
        }
    }
    catch(Exception e)
    {
        return Json(new { success = false, message = e.Message });
    }
}

Code à ajouter dans la vue

Dans ma vue maintenant, je définie une balise avec pour id reportPowerBi pour afficher mon rapport, et j’appelle ma fonction GetPowerBi() en ajax : si l’appel est un succès, j’affiche le rapport via une function loadPowerBiReport() .

<div class="tab-content full-height">
    <div id="reportPowerBi"></div>
</div>

@section Scripts {
    http://~/lib/powerbi-client/dist/powerbi.min.js
    <script type="text/javascript">

    (function () {
        $(document).ready(function () {
            $.ajax({
                url: '/Home/GetPowerBi',
                type: 'GET',
                cache: false,
                success: function (result) {
                    if (result.success) {
                        loadPowerBiReport(result);
                    } else {
                        $("#reportPowerBi").append("Rapport non récupéré");
                    }
                },
                error: function (request, status, error) {
                    alert("Erreur :" + request.responseText);
                }
            });


            function loadPowerBiReport(result) {
                // A DEFINIR
            }
        });
    })();
    </script>
}

Je n’oublie pas d’intégrer ma library powerbi-client :

http://~/lib/powerbi-client/dist/powerbi.min.js

J’affiche ensuite le rapport via cette library en complétant ma fonction loadPowerBiReport() :

function loadPowerBiReport(result) {
                var models = window['powerbi-client'].models;

                //result.reports.forEach(function (rapport) {

                // Embed configuration used to describe the what and how to embed.
                // This object is used when calling powerbi.embed.
                // This also includes settings and options such as filters.
                // You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details.
                var config = {
                    type: 'report',
                    id: result.report.id,
                    tokenType: models.TokenType.Aad,
                    accessToken: result.accessToken,
                    embedUrl: result.report.embedUrl
                };

                // Grab the reference to the div HTML element that will host the report.
                var reportDiv = $('#reportPowerBi');

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

                // Report.on will add an event handler which prints to Log window.
                report.on("loaded", function () {
                    // Report.off removes a given event handler if it exists.
                    report.off("loaded");
                });

                // Report.on will add an event handler which prints to Log window.
                report.on("rendered", function () {
                    // Report.off removes a given event handler if it exists.
                    report.off("rendered");
                });
                //});
            }

Après compilation et exécution de mon code, je récupère mon rapport Power Bi (bien entendu, l’affichage peut être optimisée lors de la récupération côté JavaScript ou en CSS).

Récupération du rapport

Vous savez désormais récupérer les rapports Power Bi dans vos applications .Net Core !

Plus d’articles :

Le paiement mobile

Le paiement mobile

Quels sont les pros et les cons de ce nouveau mode de paiement ? Quelles sont les technologies d’intelligences artificielles derrière cette révolution de paiement ? Quels enjeux envisage-t-on dans un futur proche ?