March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount! Early bird discount ends December 31.
Register NowBe one of the first to start using Fabric Databases. View on-demand sessions with database experts and the Microsoft product team to learn just how easy it is to get started. Watch now
For tiles on a dashboard with the external link defined, where can I find that url from the tileclicked event?
When I look at the event.detail in the following code, there's no reference to a external link URL
dashboard.on("tileClicked", function (event) {
alert(JSON.stringfy(event.detail));
});
Solved! Go to Solution.
I just tested and found that only when the "Set cutom link" is checked then the reponse JSON would contains the filed "targetUrl", otherwise the field "targetUrl" is missing instead of showing blank.
@cch1 wrote:
For tiles on a dashboard with the external link defined, where can I find that url from the tileclicked event?
When I look at the event.detail in the following code, there's no reference to a external link URL
dashboard.on("tileClicked", function (event) {
alert(JSON.stringfy(event.detail));
});
If you mean the external link set in Power BI service, AFAIK, it is not possible to get it. As when clicking on the tiles of an embedded dashboard, it doesn't navigate any page as the clicking on tiles does in Power BI Service. Per my understanding, it is dependent from the Power BI service.
However you could get the target url of a tile with Power BI REST API, see Get Tiles.
Hi Eric,
The GetTiles link you referred me to (https://msdn.microsoft.com/en-us/library/mt465741.aspx?f=255&MSPPError=-2147217396) doesn't have an targetUrl field in its response.
it's different than the results you're showing. What is the correct method to use to get a dashboard tile's
I'm referring to your original response:
I just tested and found that only when the "Set cutom link" is checked then the reponse JSON would contains the filed "targetUrl", otherwise the field "targetUrl" is missing instead of showing blank.
Hi Eric,
Thanks for the reply.
Is the get tiles operation possible wher the app was registered as a native app (registered on dev.powerbi.com/apps)? From the sample code, to call the gettiles(), the app requires an access token which is dependednt on a client secret, which is not provided when the app is registered as a native app (in powerbi sample terminology - app owns the data vs the user owns the data).
We're trying to embed a dashboard where the user does NOT have to login as a powerbi user (the powerbi username/password is hardcoded into the application).
Hi Eric,
Based on your suggestion, I tried to access the PowerBI REST APIs; however, when I try to access it, I receive a 403 Forbidden error.
Sample Code:
string Username = ConfigurationManager.AppSettings["pbiUsername"];
string Password = ConfigurationManager.AppSettings["pbiPassword"];
string AuthorityUrl = ConfigurationManager.AppSettings["authorityUrl"];
string ResourceUrl = ConfigurationManager.AppSettings["resourceUrl"];
string ClientId = ConfigurationManager.AppSettings["clientId"];
string ApiUrl = ConfigurationManager.AppSettings["apiUrl"];
string GroupId = ConfigurationManager.AppSettings["groupId"];
var error = GetWebConfigErrors(ClientId, GroupId, Username, Password);
if (error != null)
{
return new ReportListingViewModel()
{
ErrorMessage = error
};
}
// 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 new ReportListingViewModel()
{
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 dashboards.
var dashboards = await client.Dashboards.GetDashboardsInGroupAsync(GroupId);
// Get the first report in the group.
Dashboard dashboard = null;
foreach (var d in dashboards.Value)
{
if (d.DisplayName.ToUpper().Trim() == _GetDashboardByUserName())
{
dashboard = d;
var oTiles = await client.Dashboards.GetTilesInGroupAsync(GroupId, d.Id);
foreach (var t in oTiles.Value)
{
string s = t.EmbedData; // **** Note the EmbedData is always NULL, even for those tiles with external link defined.
}
break;
}
}
if (dashboard == null)
{
logger.Error("_GetDashboardData: Group has no dashboards.");
return new ReportListingViewModel()
{
ErrorMessage = "Group has no dashboards."
};
}
// Generate Embed Token.
var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");
var tokenResponse = await client.Dashboards.GenerateTokenInGroupAsync(GroupId, dashboard.Id, generateTokenRequestParameters);
if (tokenResponse == null)
{
return new ReportListingViewModel()
{
ErrorMessage = "Failed to generate embed token."
};
}
//Configure tiles request
System.Net.WebRequest request = System.Net.WebRequest.Create(
String.Format("{0}Dashboards/{1}/Tiles",
@"https://api.powerbi.com/v1.0/myorg/",
@"<My dashboard ID>")) as System.Net.HttpWebRequest;
request.Method = "GET";
request.ContentLength = 0;
request.Headers.Add("Authorization", String.Format("Bearer {0}", tokenResponse.Token));
// **** I receive a 403 error exception when I call request.GetResponse()
using (var response = request.GetResponse() as System.Net.HttpWebResponse)
{
//Get reader from response stream
using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
{
//Deserialize JSON string
PBITiles tiles = JsonConvert.DeserializeObject<PBITiles>(reader.ReadToEnd());
//Sample assumes at least one Dashboard with one Tile.
if (tiles.value.Length > 0)
{
string r = tiles.value[0].embedUrl;
}
}
}
// Generate Embed Configuration.
var embedConfig = new ReportListingViewModel()
{
EmbedToken = tokenResponse,
EmbedUrl = dashboard.EmbedUrl,
Id = dashboard.Id,
};
return embedConfig;
Have you picked up all permission for the registered app and grant permissions(how?) to the account used to generate accesstoken? I have no problem calling the Get Tiles with a native app. For testing purpose, you could try to get an accesstoken as below.
static string getAccessTokenSilently() { HttpWebRequest request = System.Net.HttpWebRequest.CreateHttp("https://login.windows.net/common/oauth2/token"); //POST web request to create a datasource. request.KeepAlive = true; request.Method = "POST"; request.ContentLength = 0; request.ContentType = "application/x-www-form-urlencoded"; //Add token to the request header request.Headers.Add("Authorization", String.Format("Bearer {0}", token)); NameValueCollection parsedQueryString = HttpUtility.ParseQueryString(String.Empty); parsedQueryString.Add("client_id", {clientID}); parsedQueryString.Add("grant_type", "password"); parsedQueryString.Add("resource", "https://analysis.windows.net/powerbi/api"); parsedQueryString.Add("username", {yourusername}); parsedQueryString.Add("password", {yourpassword}); string postdata = parsedQueryString.ToString(); //POST web request byte[] dataByteArray = System.Text.Encoding.ASCII.GetBytes(postdata); ; request.ContentLength = dataByteArray.Length; //Write JSON byte[] into a Stream using (Stream writer = request.GetRequestStream()) { writer.Write(dataByteArray, 0, dataByteArray.Length); var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); dynamic responseJson = JsonConvert.DeserializeObject<dynamic>(responseString); return responseJson["access_token"]; } }
Hi Eric,
Thanks for the last code snippet, I'm able to connect to the tiles via (https://api.powerbi.com/v1.0/myorg/groups/{group_id}/dashboards/{dashboard_id}/tiles); however, the response that's returned is the following as per the get tiles documentation. There's no action or targetUrl element as per your original reply.
Where can I find the tile's targetUrl? Can you provide sample code that retrieves this value?
{ "@odata.context":"https://api.powerbi.com/v1.0/myorg/$metadata#tiles","value": [ { "id":"{tile_guid}", "title":"tile_title", "embedUrl":"https://api.powerbi.com/embed?dashboardId={dashboard_id}&tileId={title_id}" } ] }
Hi Eric,
From my previous post, this is the based I'm currently using:
string Username = ConfigurationManager.AppSettings["pbiUsername"]; string Password = ConfigurationManager.AppSettings["pbiPassword"]; string AuthorityUrl = ConfigurationManager.AppSettings["authorityUrl"]; string ResourceUrl = ConfigurationManager.AppSettings["resourceUrl"]; string ClientId = ConfigurationManager.AppSettings["clientId"]; string ApiUrl = ConfigurationManager.AppSettings["apiUrl"]; string GroupId = ConfigurationManager.AppSettings["groupId"]; var error = GetWebConfigErrors(ClientId, GroupId, Username, Password); if (error != null) { return new ReportListingViewModel() { ErrorMessage = error }; } // 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 new ReportListingViewModel() { 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 dashboards. var dashboards = await client.Dashboards.GetDashboardsInGroupAsync(GroupId); // Get the first report in the group. Dashboard dashboard = null; foreach (var d in dashboards.Value) { if (d.DisplayName.ToUpper().Trim() == _GetDashboardByUserName()) { dashboard = d; break; } } if (dashboard == null) { return new ReportListingViewModel() { ErrorMessage = "Group has no dashboards." }; } // Generate Embed Token. var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view"); var tokenResponse = await client.Dashboards.GenerateTokenInGroupAsync(GroupId, dashboard.Id, generateTokenRequestParameters); if (tokenResponse == null) { return new ReportListingViewModel() { ErrorMessage = "Failed to generate embed token." }; } HttpWebRequest request = System.Net.HttpWebRequest.CreateHttp("https://login.windows.net/common/oauth2/token"); //POST web request to create a datasource. request.KeepAlive = true; request.Method = "POST"; request.ContentLength = 0; request.ContentType = "application/x-www-form-urlencoded"; //Add token to the request header request.Headers.Add("Authorization", String.Format("Bearer {0}", authenticationResult.AccessToken)); NameValueCollection parsedQueryString = HttpUtility.ParseQueryString(String.Empty); parsedQueryString.Add("client_id", ClientId); parsedQueryString.Add("grant_type", "password"); parsedQueryString.Add("resource", @"https://analysis.windows.net/powerbi/api"); parsedQueryString.Add("username", Username); parsedQueryString.Add("password", Password); string postdata = parsedQueryString.ToString(); //POST web request byte[] dataByteArray = System.Text.Encoding.ASCII.GetBytes(postdata); ; request.ContentLength = dataByteArray.Length; //Write JSON byte[] into a Stream using (Stream writer = request.GetRequestStream()) { writer.Write(dataByteArray, 0, dataByteArray.Length); var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); dynamic responseJson = JsonConvert.DeserializeObject<dynamic>(responseString); //Configure tiles request System.Net.WebRequest req = System.Net.WebRequest.Create( String.Format("{0}groups/{1}/Dashboards/{2}/Tiles", @"https://api.powerbi.com/v1.0/myorg/", GroupId, @"<MY DASHBOARD ID>")) as System.Net.HttpWebRequest; req.Method = "GET"; req.ContentLength = 0; req.Headers.Add("Authorization", String.Format("Bearer {0}", responseJson["access_token"])); //Get tiles response from request.GetResponse() using (var resp = req.GetResponse() as System.Net.HttpWebResponse) { //Get reader from response stream using (var reader = new System.IO.StreamReader(resp.GetResponseStream())) { //Deserialize JSON string PBITiles tiles = JsonConvert.DeserializeObject<PBITiles>(reader.ReadToEnd()); //Sample assumes at least one Dashboard with one Tile. //You could write an app that lists all tiles in a dashboard if (tiles.value.Length > 0) { string r = tiles.value[0].embedUrl; } } } }
March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!
Your insights matter. That’s why we created a quick survey to learn about your experience finding answers to technical questions.
Arun Ulag shares exciting details about the Microsoft Fabric Conference 2025, which will be held in Las Vegas, NV.
User | Count |
---|---|
7 | |
3 | |
2 | |
1 | |
1 |
User | Count |
---|---|
8 | |
3 | |
2 | |
2 | |
2 |