Power BI 报表未加载到 MVC 应用程序中
Power BI report is not loading in MVC application
几天前我学会了在 Power BI 中制作报告,学习 Power BI 是一次很棒的经历。当我为基于 MVC 的 Web 应用程序创建仪表板时,我想让仪表板的外观和填充更具吸引力。我正在考虑将 Power BI 报告嵌入其中,因为我在视图中使用了以下代码:-
<body>
<script type="text/javascript" src="~/Scripts/PowerBI/powerbi.js"></script>
<script type="text/javascript">
window.onload = function () {
var iframe = document.getElementById("iFrameEmbedReport");
iframe.src = "https://app.powerbi.com/reportEmbed?reportId=" + embedReportId;
iframe.onload = postActionLoadReport;
}
function postActionLoadReport() {
var m = {
action: "loadReport",
accessToken: accessToken
};
message = JSON.stringify(m);
iframe = document.getElementById("iFrameEmbedReport");
iframe.contentWindow.postMessage(message, "*");;
}
</script>
<style>
#iFrameEmbedReport {
width: 95%;
height: 95%;
}
</style>
<iframe ID="iFrameEmbedReport"></iframe>
</body>
控制器代码如下:-
public class DashBoardController : Controller
{
string baseUri = WebConfigurationManager.AppSettings["PowerBiDataset"];
string AccessToken = string.Empty;
// GET: DashBoard
public ActionResult DashBoard()
{
if (Request.Params.Get("code") != null)
{
Session["AccessToken"] = GetAccessToken(
Request.Params.GetValues("code")[0],
WebConfigurationManager.AppSettings["ClientID"],
WebConfigurationManager.AppSettings["ClientSecret"],
WebConfigurationManager.AppSettings["RedirectUrl"]);
Response.Redirect("~/DashBoard/DashBoard");
}
if (Session["AccessToken"] != null)
{
AccessToken = Session["AccessToken"].ToString();
GetReport(0);
}
return View();
}
protected void GetReport(int index)
{
System.Net.WebRequest request = System.Net.WebRequest.Create(
String.Format("{0}/Reports",
baseUri)) as System.Net.HttpWebRequest;
request.Method = "GET";
request.ContentLength = 0;
request.Headers.Add("Authorization", String.Format("Bearer {0}", AccessToken));
using (var response = request.GetResponse() as System.Net.HttpWebResponse)
{
using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
{
PBIReports Reports = JsonConvert.DeserializeObject<PBIReports>(reader.ReadToEnd());
if (Reports.value.Length > 0)
{
var report = Reports.value[index];
ViewData["AccessToken"] = Session["AccessToken"].ToString();
ViewData["EmbedURL"] = report.embedUrl;
ViewData["ReportID"] = report.id;
}
}
}
}
public void GetAuthorizationCode()
{
var @params = new NameValueCollection
{
{"response_type", "code"},
{"client_id", WebConfigurationManager.AppSettings["ClientID"]},
{"resource", WebConfigurationManager.AppSettings["PowerBiAPI"]},
{ "redirect_uri", WebConfigurationManager.AppSettings["RedirectUrl"]}
};
var queryString = HttpUtility.ParseQueryString(string.Empty);
queryString.Add(@params);
Response.Redirect(String.Format(WebConfigurationManager.AppSettings["AADAuthorityUri"] + "?{0}", queryString));
}
public string GetAccessToken(string authorizationCode, string clientID, string clientSecret, string redirectUri)
{
TokenCache TC = new TokenCache();
string authority = WebConfigurationManager.AppSettings["AADAuthorityUri"];
AuthenticationContext AC = new AuthenticationContext(authority, TC);
ClientCredential cc = new ClientCredential(clientID, clientSecret);
return AC.AcquireTokenByAuthorizationCode(
authorizationCode,
new Uri(redirectUri), cc).AccessToken;
}
}
public class PBIReports
{
public PBIReport[] value { get; set; }
}
public class PBIReport
{
public string id { get; set; }
public string name { get; set; }
public string webUrl { get; set; }
public string embedUrl { get; set; }
}
正如我所想,我做的一切都是正确的,但我不知道为什么它无法显示报告。如果我在上面给定的代码中有任何错误,请建议我。
不清楚错误出在哪里,因为您提供了很多代码,但没有说明错误本身。这里有几点需要注意:
- 要在您的 HTML 中嵌入 Power BI 内容,您只需要一个空的
div
元素
- 整体代码太多。
您需要执行以下步骤:
- 使用
AuthenticationContext.AcquireTokenAsync
和在 Power BI 端提供的凭据获取身份验证令牌
- 用刚刚获得的token实例化
PowerBIClient
。那是您的应用程序的令牌。切勿将其传递给用户。不要存储在 Session 中,因为它会过期。 PowerBIClient(new Uri(_Context.ApiUrl), new TokenCredentials(authResult.AccessToken, "Bearer"))
- 获取 Power BI 中可用内容的 ID。对于不同类型(仪表板、报告、磁贴)以及是否在组(工作区)中的内容,例如,有不同的 API。
client.Dashboards.GetDashboardsInGroupAsync(GroupId)
。如果您已经知道您获得的内容类型及其 ID,则可以跳过此步骤。请记住,如果 EmbedUrl
属性 在返回的对象上为空,您将无法渲染,即使您手动构造这样的 url.
- 为特定内容获取嵌入令牌。有不同的方法可用,例如
client.Reports.GenerateTokenInGroupAsync(GroupId, Id-of-content, new GenerateTokenRequest(accessLevel: "view"))
- 最后一步是在客户端应用 Embed Token 和 EmbedUrl。以下几行中的内容:
.
var embedToken = $('#embedToken').val();
var txtEmbedUrl = $('#txtReportEmbed').val();
var txtEmbedReportId = $('#txtEmbedReportId').val();
var models = window['powerbi-client'].models;
var permissions = models.Permissions.All;
var config= {
type: 'report',
tokenType: models.TokenType.Embed,
accessToken: embedToken,
embedUrl: txtEmbedUrl,
id: txtEmbedReportId,
permissions: permissions,
settings: {
filterPaneEnabled: true,
navContentPaneEnabled: true
}
};
var embedContainer = $('#embedContainer')[0];
var report = powerbi.embed(embedContainer, config);
你应该可以测试你的东西 here。只需插入您的价值观。
您也可以在此处查看示例应用]2。上面提供的流程适用于 "app owns data" 个案例。
几天前我学会了在 Power BI 中制作报告,学习 Power BI 是一次很棒的经历。当我为基于 MVC 的 Web 应用程序创建仪表板时,我想让仪表板的外观和填充更具吸引力。我正在考虑将 Power BI 报告嵌入其中,因为我在视图中使用了以下代码:-
<body>
<script type="text/javascript" src="~/Scripts/PowerBI/powerbi.js"></script>
<script type="text/javascript">
window.onload = function () {
var iframe = document.getElementById("iFrameEmbedReport");
iframe.src = "https://app.powerbi.com/reportEmbed?reportId=" + embedReportId;
iframe.onload = postActionLoadReport;
}
function postActionLoadReport() {
var m = {
action: "loadReport",
accessToken: accessToken
};
message = JSON.stringify(m);
iframe = document.getElementById("iFrameEmbedReport");
iframe.contentWindow.postMessage(message, "*");;
}
</script>
<style>
#iFrameEmbedReport {
width: 95%;
height: 95%;
}
</style>
<iframe ID="iFrameEmbedReport"></iframe>
</body>
控制器代码如下:-
public class DashBoardController : Controller
{
string baseUri = WebConfigurationManager.AppSettings["PowerBiDataset"];
string AccessToken = string.Empty;
// GET: DashBoard
public ActionResult DashBoard()
{
if (Request.Params.Get("code") != null)
{
Session["AccessToken"] = GetAccessToken(
Request.Params.GetValues("code")[0],
WebConfigurationManager.AppSettings["ClientID"],
WebConfigurationManager.AppSettings["ClientSecret"],
WebConfigurationManager.AppSettings["RedirectUrl"]);
Response.Redirect("~/DashBoard/DashBoard");
}
if (Session["AccessToken"] != null)
{
AccessToken = Session["AccessToken"].ToString();
GetReport(0);
}
return View();
}
protected void GetReport(int index)
{
System.Net.WebRequest request = System.Net.WebRequest.Create(
String.Format("{0}/Reports",
baseUri)) as System.Net.HttpWebRequest;
request.Method = "GET";
request.ContentLength = 0;
request.Headers.Add("Authorization", String.Format("Bearer {0}", AccessToken));
using (var response = request.GetResponse() as System.Net.HttpWebResponse)
{
using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
{
PBIReports Reports = JsonConvert.DeserializeObject<PBIReports>(reader.ReadToEnd());
if (Reports.value.Length > 0)
{
var report = Reports.value[index];
ViewData["AccessToken"] = Session["AccessToken"].ToString();
ViewData["EmbedURL"] = report.embedUrl;
ViewData["ReportID"] = report.id;
}
}
}
}
public void GetAuthorizationCode()
{
var @params = new NameValueCollection
{
{"response_type", "code"},
{"client_id", WebConfigurationManager.AppSettings["ClientID"]},
{"resource", WebConfigurationManager.AppSettings["PowerBiAPI"]},
{ "redirect_uri", WebConfigurationManager.AppSettings["RedirectUrl"]}
};
var queryString = HttpUtility.ParseQueryString(string.Empty);
queryString.Add(@params);
Response.Redirect(String.Format(WebConfigurationManager.AppSettings["AADAuthorityUri"] + "?{0}", queryString));
}
public string GetAccessToken(string authorizationCode, string clientID, string clientSecret, string redirectUri)
{
TokenCache TC = new TokenCache();
string authority = WebConfigurationManager.AppSettings["AADAuthorityUri"];
AuthenticationContext AC = new AuthenticationContext(authority, TC);
ClientCredential cc = new ClientCredential(clientID, clientSecret);
return AC.AcquireTokenByAuthorizationCode(
authorizationCode,
new Uri(redirectUri), cc).AccessToken;
}
}
public class PBIReports
{
public PBIReport[] value { get; set; }
}
public class PBIReport
{
public string id { get; set; }
public string name { get; set; }
public string webUrl { get; set; }
public string embedUrl { get; set; }
}
正如我所想,我做的一切都是正确的,但我不知道为什么它无法显示报告。如果我在上面给定的代码中有任何错误,请建议我。
不清楚错误出在哪里,因为您提供了很多代码,但没有说明错误本身。这里有几点需要注意:
- 要在您的 HTML 中嵌入 Power BI 内容,您只需要一个空的
div
元素 - 整体代码太多。
您需要执行以下步骤:
- 使用
AuthenticationContext.AcquireTokenAsync
和在 Power BI 端提供的凭据获取身份验证令牌 - 用刚刚获得的token实例化
PowerBIClient
。那是您的应用程序的令牌。切勿将其传递给用户。不要存储在 Session 中,因为它会过期。PowerBIClient(new Uri(_Context.ApiUrl), new TokenCredentials(authResult.AccessToken, "Bearer"))
- 获取 Power BI 中可用内容的 ID。对于不同类型(仪表板、报告、磁贴)以及是否在组(工作区)中的内容,例如,有不同的 API。
client.Dashboards.GetDashboardsInGroupAsync(GroupId)
。如果您已经知道您获得的内容类型及其 ID,则可以跳过此步骤。请记住,如果EmbedUrl
属性 在返回的对象上为空,您将无法渲染,即使您手动构造这样的 url. - 为特定内容获取嵌入令牌。有不同的方法可用,例如
client.Reports.GenerateTokenInGroupAsync(GroupId, Id-of-content, new GenerateTokenRequest(accessLevel: "view"))
- 最后一步是在客户端应用 Embed Token 和 EmbedUrl。以下几行中的内容:
.
var embedToken = $('#embedToken').val();
var txtEmbedUrl = $('#txtReportEmbed').val();
var txtEmbedReportId = $('#txtEmbedReportId').val();
var models = window['powerbi-client'].models;
var permissions = models.Permissions.All;
var config= {
type: 'report',
tokenType: models.TokenType.Embed,
accessToken: embedToken,
embedUrl: txtEmbedUrl,
id: txtEmbedReportId,
permissions: permissions,
settings: {
filterPaneEnabled: true,
navContentPaneEnabled: true
}
};
var embedContainer = $('#embedContainer')[0];
var report = powerbi.embed(embedContainer, config);
你应该可以测试你的东西 here。只需插入您的价值观。
您也可以在此处查看示例应用]2。上面提供的流程适用于 "app owns data" 个案例。