在 ASP.Net Core 网站中嵌入 Power BI 报告 [英] Embed Power BI Report In ASP.Net Core Website

查看:46
本文介绍了在 ASP.Net Core 网站中嵌入 Power BI 报告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ASP.Net core 1.1 网站,我想将 Power BI 报告嵌入该网站.

I have an ASP.Net core 1.1 website and I want to embed power BI reports into the site.

Azure 托管数据文档:https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-embed-sample-app-owns-data/

Azure Hosted Data documentation: https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-embed-sample-app-owns-data/

使用https://github上的应用拥有数据示例.com/Microsoft/PowerBI-Developer-Samples 我有一个使用该示例的有效嵌入式报告解决方案.但是,示例项目在 .Net Framework 4.5.2 上运行,当我尝试将解决方案迁移到我的 .Net 核心应用程序时,我已经迁移了代码,但是 .Net Core 中的 ActiveDirectorylibrary (Microsoft.IdentityModel.Clients.ActiveDirectorylibrary) 没有包含 UserPasswordCredential 的方法

Using the App Owns Data sample found at https://github.com/Microsoft/PowerBI-Developer-Samples I have a working embedded reports solution using the sample. However, the sample project is running on .Net Framework 4.5.2 and When trying to migrate the solution into my .Net core application I have migrated the code however the ActiveDirectorylibrary (Microsoft.IdentityModel.Clients.ActiveDirectorylibrary) in .Net Core does not contain a method for UserPasswordCredential

        var credential = new UserPasswordCredential(Username, Password);

我在网上为 ASP.Net 核心推荐的解决方案是使用标签助手,但是现在 Power BI Embedded 和 Power BI 服务已经与 Power BI Premium 的新版本融合,我认为这个解决方案是不可能的由于应用托管数据依赖于令牌身份验证.

The solution that I found recommended online for ASP.Net core is to use a tag helper however now that the Power BI Embedded and Power BI service have converged with the new arrival of Power BI Premium I dont think think this solutions is possible due to the depencency on token authentication for the App Hosted data.

完整的报表控制器方法:

Full Report Controller Method:

            public class ReportController : Controller
    {
        private static readonly string Username = ConfigurationManager.AppSettings["pbiUsername"];
        private static readonly string Password = ConfigurationManager.AppSettings["pbiPassword"];
        private static readonly string AuthorityUrl = ConfigurationManager.AppSettings["authorityUrl"];
        private static readonly string ResourceUrl = ConfigurationManager.AppSettings["resourceUrl"];
        private static readonly string ClientId = ConfigurationManager.AppSettings["clientId"];
        private static readonly string ApiUrl = ConfigurationManager.AppSettings["apiUrl"];
        private static readonly string GroupId = ConfigurationManager.AppSettings["groupId"];

    public async Task<ActionResult> EmbedReport()
    {
        // Create a user password cradentials.
        var credential = new UserPasswordCredential(Username, Password);

        // Authenticate using created credentials
        var authenticationContext = new AuthenticationContext(AuthorityUrl);
        var authenticationResult = await authenticationContext.AcquireTokenAsync(ResourceUrl, ClientId, credential);

        if (authenticationResult == null)
        {
            return View(new EmbedConfig()
            {
                ErrorMessage = "Authentication Failed."
            });
        }

        var tokenCredentials = new TokenCredentials(authenticationResult.AccessToken, "Bearer");

        // Create a Power BI Client object. It will be used to call Power BI APIs.
        using (var client = new PowerBIClient(new Uri(ApiUrl), tokenCredentials))
        {
            // Get a list of reports.
            var reports = await client.Reports.GetReportsInGroupAsync(GroupId);

            // Get the first report in the group.
            var report = reports.Value.FirstOrDefault();

            if (report == null)
            {
                return View(new EmbedConfig()
                {
                    ErrorMessage = "Group has no reports."
                });
            }

            // Generate Embed Token.
            var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");
            var tokenResponse = await client.Reports.GenerateTokenInGroupAsync(GroupId, report.Id, generateTokenRequestParameters);

            if (tokenResponse == null)
            {
                return View(new EmbedConfig()
                {
                    ErrorMessage = "Failed to generate embed token."
                });
            }

            // Generate Embed Configuration.
            var embedConfig = new EmbedConfig()
            {
                EmbedToken = tokenResponse,
                EmbedUrl = report.EmbedUrl,
                Id = report.Id
            };

            return View(embedConfig);
        }
    }
}

我尝试过的:

在 .Net Core 项目中添加对 .Net Framework 4.6.1 的引用以公开 .Net Framework 并允许使用 IdentityModel.Clients.ActiveDirectory 的 .Net 等效项,但这似乎没有帮助.

Adding a reference to .Net Framework 4.6.1 in the .Net Core project to expose the .Net Framework and allow the use of the .Net equivalent of the IdentityModel.Clients.ActiveDirectory but that did not seem to help.

如何修复库问题并嵌入 .Net 核心?

How can I fix the library issue and embedding in .Net core?

根据@Fei Xue 提供的答案,我编写了一个 HTTP 帮助程序类,该类对 API 执行发布操作.基于返回的 JSON,我创建了一个对象并使用了现在可用的身份验证令牌

Based off of the answer provided by @Fei Xue I wrote an HTTP helper class that performed a post to the API. Based off of the returned JSON I create an object and used the now available authentication token

助手类:

  #region Settings

    public static string BaseUrl
    {
        get
        {
            return "https://login.microsoftonline.com/common/oauth2/token";
        }
    }

    #endregion

    public static async Task<HttpResponseMessage> MakeAsyncRequest(string url, Dictionary<string, string> content)
    {
        var httpClient = new HttpClient
        {
            Timeout = new TimeSpan(0, 5, 0),
            BaseAddress = new Uri(url)
        };

        httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type: application/x-www-form-urlencoded", "application/json");

        if (content == null)
        {
            content = new Dictionary<string, string>();
        }

        var encodedContent = new FormUrlEncodedContent(content);

        var result = await httpClient.PostAsync(httpClient.BaseAddress, encodedContent);

        return result;
    }

对象:

 public class AAD
{
    public string token_type { get; set; }
    public string scope { get; set; }
    public string expires_in { get; set; }
    public string ext_expires_in { get; set; }
    public string expires_on { get; set; }
    public string not_before { get; set; }
    public string resource { get; set; }
    public string access_token { get; set; }
    public string refresh_token { get; set; }
}

来自控制器的调用:

            var url = APIHelper.BaseUrl;
        var content = new Dictionary<string, string>();
        content["grant_type"] = "password";
        content["resource"] = "https://analysis.windows.net/powerbi/api";
        content["username"] = "<username>";
        content["password"] = "<password>";
        content["client_id"] = "<clientid>";

        var response = await APIHelper.MakeAsyncRequest(url, content);
        var result = response.Content.ReadAsStringAsync().Result;
        var AAD = JsonConvert.DeserializeObject<AAD>(result);

推荐答案

Active Directory 身份验证库的 .Net 核心不支持资源所有者密码凭据流.

The resource owner password credentials flow is not supported for the .Net core for Active Directory Authentication Library.

作为一种解决方法,您可以直接编写 HTTP 请求.这是一个示例供您参考:

As a workaround, you can compose the HTTP request directly. Here is a example for your reference:

POST https://login.microsoftonline.com/{tenant}/oauth2/token 
Content-Type: application/x-www-form-urlencoded

grant_type=password
&resource={resource}
&username={username}
&password={password}
&client_id={clientid}
&client_secret={client_secret}//if it is confidential app

这篇关于在 ASP.Net Core 网站中嵌入 Power BI 报告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆