I'm having a problem saving a report across different workspaces in PowerBI embedded. For background:
If I use the built in PowerBI save functionality, it always saves to the workspace where the dataset resides (and it works perfectly fine, which makes be believe the issue is not down to the EmbedToken being generated which is why I've omitted it here).
I've implemented functionality in the Razor View as per below (based on the official Microsoft documentation) to save the report to a defined workspace using the targetWorkspaceId defined in the saveAsParameters.
<script>
var accessToken = '@Model.EmbedToken.Token';
var models = window['powerbi-client'].models;
var config = {
tokenType: models.TokenType.Embed,
accessToken: accessToken,
datasetId: '@Model.DatasetId.ToString()',
embedUrl: 'https://embedded.powerbi.com/ReportEmbed',
permissions: models.Permissions.All,
settings: {
useCustomSaveAsDialog: true
}
};
// Get a reference to the embedded report HTML element
var reportContainer = $('#reportContainer')[0];
// Embed the report and display it within the div container.
let report = powerbi.createReport(reportContainer, config);
report.on("saveAsTriggered", function (event) {
showModal();
});
function showModal() {
$('#savereport').modal('show');
}
function saveAs() {
let saveAsParameters = {
name: $('#ReportName').val(),
targetWorkspaceId: '@Model.WorkspaceId'
}
var result = report.saveAs(saveAsParameters);
}
// add event handler to load existing report afer saving new report
report.on("saved", function (event) {
alert("Report Saved");
window.location.href = "/Reporting/View?Id=" + event.detail.reportObjectId;
});
</script>
I can see from the JSON generated in the request that the target workspace is being called.
And the response is 403 Forbidden
The PowerBI Embedded error screen
Interestingly, it even fails if I try to save to the workspace where the dataset resides which is confusing me.
If I omit the targetWorkspaceId from the saveAsParameters it saves absolutely fine - just not in the desired workspace! Does anybody have any ideas?
Thanks to Andrey for pointing me to the documentation. The issue was I was using GenerateTokenRequest within the C# SDK whereas I should have been using GenerateTokenRequestV2. Working code is below.
public async Task<EmbedConfig> CreateNewReport()
{
try
{
var result = new EmbedConfig { };
var accessToken = await GetPowerBIAccessTokenAsync();
var tokenCredentials = new TokenCredentials(accessToken, "Bearer");
using var client = new PowerBIClient(new Uri(_powerBISettings.ApiUrl), tokenCredentials);
var identities = new List<EffectiveIdentity> { new EffectiveIdentity(username: _tenant.Id.ToString(), roles: new List<string> { "Tenant" }, datasets: new List<string> { _powerBISettings.DatasetId.ToString() }) };
// old method
//var generateTokenRequestParameters = new GenerateTokenRequest(TokenAccessLevel.Create, identities: identites, datasetId: _powerBISettings.DatasetId.ToString(), allowSaveAs: true);
//EmbedToken tokenResponse = await client.Reports.GenerateTokenForCreateInGroupAsync(_tenant.PowerBIWorkspaceId.Value, generateTokenRequestParameters);
var generateTokenRequestParameters = new GenerateTokenRequestV2(datasets: new List<GenerateTokenRequestV2Dataset> { new GenerateTokenRequestV2Dataset(_powerBISettings.DatasetId.ToString()) }, targetWorkspaces: new List<GenerateTokenRequestV2TargetWorkspace> { new GenerateTokenRequestV2TargetWorkspace(_tenant.PowerBIWorkspaceId.Value) }, identities: identities );
EmbedToken tokenResponse = await client.EmbedToken.GenerateTokenAsync(generateTokenRequestParameters);
result.EmbedToken = tokenResponse;
result.DatasetId = _powerBISettings.DatasetId.ToString();
result.WorkspaceId = _tenant.PowerBIWorkspaceId?.ToString() ?? throw new NullReferenceException("No Power BI workspace set");
return result;
}
catch (Exception exception)
{
throw;
}
}