Starting December 3, join live sessions with database experts and the Microsoft product team to learn just how easy it is to get started
Learn moreGet certified in Microsoft Fabric—for free! For a limited time, get a free DP-600 exam voucher to use by the end of 2024. Register now
private static void generateEmbedToken() { // TokenCredentials Initializes a new instance of the // Microsoft.Rest.TokenCredentials class with // the given 'Bearer' token. var credentials = new TokenCredentials(token); // Initialize PowerBIClient with credentials var powerBIclient = new Microsoft.PowerBI.Api.V2.PowerBIClient(credentials) { // BaseUri is the api endpoint, default is https://api.powerbi.com BaseUri = new Uri("https://api.powerbi.com") }; try { // Create body where accessLevel = View, datasetId = "" by default var requestParameters = new GenerateTokenRequest(TokenAccessLevel.Create, datasetId, true); // Generate EmbedToken This function sends the POST message //with all parameters and returns the token EmbedToken token = powerBIclient.Reports.GenerateTokenForCreate(requestParameters); embedToken = token.Token; } catch (Exception exc) { Console.WriteLine(exc.ToString()); } }
Microsoft.Rest.HttpOperationException: Operation returned an invalid status code 'NotFound'
at Microsoft.PowerBI.Api.V2.Reports.<GenerateTokenForCreateWithHttpMessagesAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.PowerBI.Api.V2.ReportsExtensions.<GenerateTokenForCreateAsync>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.PowerBI.Api.V2.ReportsExtensions.GenerateTokenForCreate(IReports operations, GenerateTokenRequest requestParameters)
at PushDataApp.Program.generateEmbedToken() in C:\Users\PC\Documents\Visual Studio 2017\Projects\PushDataApp\PushDataApp\Program.cs:line 388
EmbedToken token = powerBIclient.Reports.GenerateTokenForCreate(requestParameters);
Solved! Go to Solution.
I may doubt that there's some issue with the Power BI API lib, as I've found the token generation functions for reports, dashboards, tiles but not for datasets.
powerBIclient.Reports.GenerateTokenxxxxx powerBIclient.Dashboards.GenerateTokenxxxxx powerBIclient.Tiles.GenerateTokenxxxxx
So I guess for Datasets, it should be
powerBIclient.Datasets.GenerateTokenxxxxx
Unfortunately, I'm not finding any GenerateTokenxxxxx for datasets
Instead of using the API lib, call the REST API directly.
using System; //Install-Package Newtonsoft.Json using Newtonsoft.Json; using System.Net; using System.IO; namespace GenerateEmbeddedToken { class Program { static void Main(string[] args) { string EmbedTokenForDataSet = generateEmbedTokenForDataSet("the groupID", "the datasetID", "eyxxxxxxxxxtoken"); Console.WriteLine(EmbedTokenForDataSet); Console.ReadKey(); } private static string generateEmbedTokenForDataSet(string groupID, string datasetID, string accessBearerToken) { string embedToken = ""; HttpWebRequest request = System.Net.HttpWebRequest.CreateHttp(String.Format("https://api.powerbi.com/v1.0/myorg/groups/{0}/reports/GenerateToken", groupID)); //POST web request to create a datasource. request.KeepAlive = true; request.Method = "POST"; request.ContentType = "application/json"; //Add token to the request header request.Headers.Add("Authorization", String.Format("Bearer {0}", accessBearerToken)); string PostData = "{"+ "\"accessLevel\": \"Create\","+ "\"datasetId\": \""+datasetID+"\","+ "\"allowSaveAs\": true"+ "}"; byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(PostData); try { //Write JSON byte[] into a Stream using (Stream writer = request.GetRequestStream()) { writer.Write(byteArray, 0, byteArray.Length); var response = (HttpWebResponse)request.GetResponse(); var responseJson = new StreamReader(response.GetResponseStream()).ReadToEnd(); dynamic responseString = JsonConvert.DeserializeObject<dynamic>(responseJson.ToString()); embedToken = responseString["token"]; } } catch (WebException wex) { if (wex.Response != null) { using (var errorResponse = (HttpWebResponse)wex.Response) { using (var reader = new StreamReader(errorResponse.GetResponseStream())) { string errorString = reader.ReadToEnd(); dynamic respJson = JsonConvert.DeserializeObject<dynamic>(errorString); Console.WriteLine(respJson.toString()); //TODO: use JSON.net to parse this string and look at the error message } } } } return embedToken; } } }
I may doubt that there's some issue with the Power BI API lib, as I've found the token generation functions for reports, dashboards, tiles but not for datasets.
powerBIclient.Reports.GenerateTokenxxxxx powerBIclient.Dashboards.GenerateTokenxxxxx powerBIclient.Tiles.GenerateTokenxxxxx
So I guess for Datasets, it should be
powerBIclient.Datasets.GenerateTokenxxxxx
Unfortunately, I'm not finding any GenerateTokenxxxxx for datasets
Instead of using the API lib, call the REST API directly.
using System; //Install-Package Newtonsoft.Json using Newtonsoft.Json; using System.Net; using System.IO; namespace GenerateEmbeddedToken { class Program { static void Main(string[] args) { string EmbedTokenForDataSet = generateEmbedTokenForDataSet("the groupID", "the datasetID", "eyxxxxxxxxxtoken"); Console.WriteLine(EmbedTokenForDataSet); Console.ReadKey(); } private static string generateEmbedTokenForDataSet(string groupID, string datasetID, string accessBearerToken) { string embedToken = ""; HttpWebRequest request = System.Net.HttpWebRequest.CreateHttp(String.Format("https://api.powerbi.com/v1.0/myorg/groups/{0}/reports/GenerateToken", groupID)); //POST web request to create a datasource. request.KeepAlive = true; request.Method = "POST"; request.ContentType = "application/json"; //Add token to the request header request.Headers.Add("Authorization", String.Format("Bearer {0}", accessBearerToken)); string PostData = "{"+ "\"accessLevel\": \"Create\","+ "\"datasetId\": \""+datasetID+"\","+ "\"allowSaveAs\": true"+ "}"; byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(PostData); try { //Write JSON byte[] into a Stream using (Stream writer = request.GetRequestStream()) { writer.Write(byteArray, 0, byteArray.Length); var response = (HttpWebResponse)request.GetResponse(); var responseJson = new StreamReader(response.GetResponseStream()).ReadToEnd(); dynamic responseString = JsonConvert.DeserializeObject<dynamic>(responseJson.ToString()); embedToken = responseString["token"]; } } catch (WebException wex) { if (wex.Response != null) { using (var errorResponse = (HttpWebResponse)wex.Response) { using (var reader = new StreamReader(errorResponse.GetResponseStream())) { string errorString = reader.ReadToEnd(); dynamic respJson = JsonConvert.DeserializeObject<dynamic>(errorString); Console.WriteLine(respJson.toString()); //TODO: use JSON.net to parse this string and look at the error message } } } } return embedToken; } } }
I tried to use your function, but it didn't help.
using System; //Install-Package Newtonsoft.Json using Newtonsoft.Json; using System.Net; using System.IO; namespace GenerateEmbeddedToken { class Program { static void Main(string[] args) { string EmbedTokenForDataSet = generateEmbedTokenForDataSet("the groupID", "the datasetID", "eyxxxxxxxxxtoken"); Console.WriteLine(EmbedTokenForDataSet); Console.ReadKey(); } private static string generateEmbedTokenForDataSet(string groupID, string datasetID, string accessBearerToken) { string embedToken = ""; HttpWebRequest request = System.Net.HttpWebRequest.CreateHttp(String.Format("https://api.powerbi.com/v1.0/myorg/groups/{0}/reports/GenerateToken", groupID)); //POST web request to create a datasource. request.KeepAlive = true; request.Method = "POST"; request.ContentType = "application/json"; //Add token to the request header request.Headers.Add("Authorization", String.Format("Bearer {0}", accessBearerToken)); string PostData = "{"+ "\"accessLevel\": \"Create\","+ "\"datasetId\": \""+datasetID+"\","+ "\"allowSaveAs\": true"+ "}"; byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(PostData); try { //Write JSON byte[] into a Stream using (Stream writer = request.GetRequestStream()) { writer.Write(byteArray, 0, byteArray.Length); var response = (HttpWebResponse)request.GetResponse(); var responseJson = new StreamReader(response.GetResponseStream()).ReadToEnd(); dynamic responseString = JsonConvert.DeserializeObject<dynamic>(responseJson.ToString()); embedToken = responseString["token"]; } } catch (WebException wex) { if (wex.Response != null) { using (var errorResponse = (HttpWebResponse)wex.Response) { using (var reader = new StreamReader(errorResponse.GetResponseStream())) { string errorString = reader.ReadToEnd(); dynamic respJson = JsonConvert.DeserializeObject<dynamic>(errorString); Console.WriteLine(respJson.toString()); //TODO: use JSON.net to parse this string and look at the error message } } } } return embedToken; } } }
On line:
using (Stream writer = request.GetRequestStream())
program thinks for approximately 30 seconds and then goes to catch block.
In catch block if statement is false (so, Response == null) and program just goes out from catch.
That's all.
I still don't understant why it happens because I just use this guide for POST requests (https://msdn.microsoft.com/library/mt784614.aspx). And it's up to date (Updated: July 21, 2017), so, I don't understand.
I'll appresiate any help.
@Zirochka wrote:
I tried to use your function, but it didn't help.
using System; //Install-Package Newtonsoft.Json using Newtonsoft.Json; using System.Net; using System.IO; namespace GenerateEmbeddedToken { class Program { static void Main(string[] args) { string EmbedTokenForDataSet = generateEmbedTokenForDataSet("the groupID", "the datasetID", "eyxxxxxxxxxtoken"); Console.WriteLine(EmbedTokenForDataSet); Console.ReadKey(); } private static string generateEmbedTokenForDataSet(string groupID, string datasetID, string accessBearerToken) { string embedToken = ""; HttpWebRequest request = System.Net.HttpWebRequest.CreateHttp(String.Format("https://api.powerbi.com/v1.0/myorg/groups/{0}/reports/GenerateToken", groupID)); //POST web request to create a datasource. request.KeepAlive = true; request.Method = "POST"; request.ContentType = "application/json"; //Add token to the request header request.Headers.Add("Authorization", String.Format("Bearer {0}", accessBearerToken)); string PostData = "{"+ "\"accessLevel\": \"Create\","+ "\"datasetId\": \""+datasetID+"\","+ "\"allowSaveAs\": true"+ "}"; byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(PostData); try { //Write JSON byte[] into a Stream using (Stream writer = request.GetRequestStream()) { writer.Write(byteArray, 0, byteArray.Length); var response = (HttpWebResponse)request.GetResponse(); var responseJson = new StreamReader(response.GetResponseStream()).ReadToEnd(); dynamic responseString = JsonConvert.DeserializeObject<dynamic>(responseJson.ToString()); embedToken = responseString["token"]; } } catch (WebException wex) { if (wex.Response != null) { using (var errorResponse = (HttpWebResponse)wex.Response) { using (var reader = new StreamReader(errorResponse.GetResponseStream())) { string errorString = reader.ReadToEnd(); dynamic respJson = JsonConvert.DeserializeObject<dynamic>(errorString); Console.WriteLine(respJson.toString()); //TODO: use JSON.net to parse this string and look at the error message } } } } return embedToken; } } }On line:
using (Stream writer = request.GetRequestStream())program thinks for approximately 30 seconds and then goes to catch block.
In catch block if statement is false (so, Response == null) and program just goes out from catch.
That's all.
I still don't understant why it happens because I just use this guide for POST requests (https://msdn.microsoft.com/library/mt784614.aspx). And it's up to date (Updated: July 21, 2017), so, I don't understand.
I'll appresiate any help.
Have you got any API console tool for testing purpose? If not, I'd suggest using POSTMAN.
So beforing coding in C#, can you test this GenerateToken in postman? For any issue, feel free to post.
Thanks for this Postman. It's really useful tool. Thanks a lot.
I tried to sent in this postman post request (from here https://msdn.microsoft.com/library/mt784614.aspx for dataset) and I got an answer with embed token. I checked this token here (https://microsoft.github.io/PowerBI-JavaScript/demo/v2-demo/index.html) and it works. Dataset loads to this example.
But I don't understand why from C# it doesn't works.
In my code I have another POST requests: when I create dataset (first POST) and when I push data to the dataset (second POST). And they works perfectly (I checked hundred times). But this (when I get embed token) POST (it's third POST in my code) does't work. And I found out that API works fine (thanks to postman).
Do you have any idea?
I'll appreciate any help.
@Zirochka wrote:
Thanks for this Postman. It's really useful tool. Thanks a lot.
I tried to sent in this postman post request (from here https://msdn.microsoft.com/library/mt784614.aspx for dataset) and I got an answer with embed token. I checked this token here (https://microsoft.github.io/PowerBI-JavaScript/demo/v2-demo/index.html) and it works. Dataset loads to this example.
But I don't understand why from C# it doesn't works.
In my code I have another POST requests: when I create dataset (first POST) and when I push data to the dataset (second POST). And they works perfectly (I checked hundred times). But this (when I get embed token) POST (it's third POST in my code) does't work. And I found out that API works fine (thanks to postman).
Do you have any idea?
I'll appreciate any help.
I'd say the C# code in my first indeed works as long as the groupid and datesetid are correct. In your case, as the generate embedtoken POST request works in POSTMAN, so I think you could debug your code and figure it out.
As to your "another POST requests", this is one issue as I tested in this thread and you can use the workaround from orginal poster.
Starting December 3, join live sessions with database experts and the Fabric product team to learn just how easy it is to get started.
March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount! Early Bird pricing ends December 9th.