Reputation: 73
I'm following the PowerBI Developer In A Day tutorial attempting to embed a sample dashboard into an MVC app.
https://learn.microsoft.com/en-us/power-bi/learning-catalog/developer-online-course
After a few times of going back over each section and ensuring that all of the permissions are correct in Azure, Azure AD, PowerBi, and my appsettings.json, I've been unable to resolve this issue. It seems to throw the Bad Request error whenever creating the embedToken.
An unhandled exception occurred while processing the request. HttpOperationException: Operation returned an invalid status code 'BadRequest' Microsoft.PowerBI.Api.EmbedTokenOperations.GenerateTokenWithHttpMessagesAsync(GenerateTokenRequestV2 requestParameters, Dictionary<string, List> customHeaders, CancellationToken cancellationToken)
Stack Query Cookies Headers Routing HttpOperationException: Operation returned an invalid status code 'BadRequest' Microsoft.PowerBI.Api.EmbedTokenOperations.GenerateTokenWithHttpMessagesAsync(GenerateTokenRequestV2 requestParameters, Dictionary<string, List> customHeaders, CancellationToken cancellationToken) Microsoft.PowerBI.Api.EmbedTokenOperationsExtensions.GenerateTokenAsync(IEmbedTokenOperations operations, GenerateTokenRequestV2 requestParameters, CancellationToken cancellationToken) PowerBiEmbed.Services.PowerBiApiService.GetReportsEmbeddingData() in PowerBiApiService.cs + string embedToken = (await client.EmbedToken.GenerateTokenAsync(tokenRequest)).Token; SalesReportsDemo.Controllers.HomeController.Index() in HomeController.cs + var viewModel = await _powerBiApiService.GetReportsEmbeddingData(); Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments) System.Threading.Tasks.ValueTask.get_Result() System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult() Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask actionResultValueTask) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
The class where the error is occurring:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Identity.Web;
using Microsoft.PowerBI.Api;
using Microsoft.PowerBI.Api.Models;
using Microsoft.Rest;
using Newtonsoft.Json;
using PowerBiEmbed.Models;
using PowerBiEmbed.ViewModels;
namespace PowerBiEmbed.Services
{
public class PowerBiApiService
{
private IConfiguration _configuration;
private ITokenAcquisition _tokenAcquisition;
private Uri _powerBiServiceApiRootUrl;
private Guid _workspaceId;
public const string PowerBiDefaultScope = "https://analysis.windows.net/powerbi/api/.default";
public PowerBiApiService(IConfiguration configuration, ITokenAcquisition tokenAcquisition)
{
_configuration = configuration;
_powerBiServiceApiRootUrl = new Uri(configuration["PowerBi:ServiceRootUrl"]);
_workspaceId = new Guid(configuration["PowerBi:WorkspaceId"]);
_tokenAcquisition = tokenAcquisition;
}
public string GetAccessToken()
{
return _tokenAcquisition.GetAccessTokenForAppAsync(PowerBiDefaultScope).Result;
}
public PowerBIClient GetPowerBiClient()
{
var tokenCredentials = new TokenCredentials(GetAccessToken(), "Bearer");
return new PowerBIClient(_powerBiServiceApiRootUrl, tokenCredentials);
}
public async Task<WorkspaceViewModel> GetReportsEmbeddingData()
{
// Connect to Power BI
var client = GetPowerBiClient();
// Get reports in the workspace
var reports = (await client.Reports.GetReportsInGroupAsync(_workspaceId)).Value;
var reportList = new List<EmbeddedReport>();
var reportTokenRequests = new List<GenerateTokenRequestV2Report>();
foreach (var report in reports)
{
reportList.Add(new EmbeddedReport
{
Id = report.Id.ToString(),
Name = report.Name,
EmbedUrl = report.EmbedUrl
});
reportTokenRequests.Add(new GenerateTokenRequestV2Report(report.Id, allowEdit: true));
}
// Get datasets in the workspace
var datasets = (await client.Datasets.GetDatasetsInGroupAsync(_workspaceId)).Value;
var datasetList = new List<EmbeddedDataset>();
var datasetTokenRequests = new List<GenerateTokenRequestV2Dataset>();
foreach (var dataset in datasets)
{
datasetList.Add(new EmbeddedDataset
{
Id = dataset.Id.ToString(),
Name = dataset.Name,
EmbedUrl = dataset.QnaEmbedURL
});
datasetTokenRequests.Add(new GenerateTokenRequestV2Dataset(dataset.Id));
}
// Generate token request for the workspace
var workspaceRequests = new GenerateTokenRequestV2TargetWorkspace[] {
new GenerateTokenRequestV2TargetWorkspace(_workspaceId)
};
// Bundle token requests for reports, datasets, and the workspace
var tokenRequest = new GenerateTokenRequestV2(
reports: reportTokenRequests,
datasets: datasetTokenRequests,
targetWorkspaces: workspaceRequests
);
// Generate the embed token
string embedToken = (await client.EmbedToken.GenerateTokenAsync(tokenRequest)).Token;
// Return report embedding data to caller
return new WorkspaceViewModel
{
ReportsJson = JsonConvert.SerializeObject(reportList),
DatasetsJson = JsonConvert.SerializeObject(datasetList),
EmbedToken = embedToken
};
}
}
}
Upvotes: 0
Views: 2301
Reputation: 11
I had faced to that same 'BadRequest' studying PowerBI Developer In A Day tutorial.
In this case, the problem is occurred by lack of EffectiveIdentity for each Dataset.
Before generating TokenRequest, you need to generate EffectiveIdentity too.
The following sample code could solve your problem.
var effectiveIdentities = new List<EffectiveIdentity>();
foreach (var dataset in datasets)
{
if ((bool)dataset.IsEffectiveIdentityRequired)
{
// If Dataset requires EffectiveIdentity, you need to add it.
effectiveIdentities.Add(new EffectiveIdentity(
username: <username>,
roles: new List<string>{ <roles> },
datasets: new List<string> { dataset.Id.ToString() }
));
}
}
var tokenRequest = new GenerateTokenRequestV2(
reports: reportTokenRequests,
datasets: datasetTokenRequests,
targetWorkspaces: workspaceRequests,
//When generating token, set EffectiveIdentities.
identities: effectiveIdentities
);
These also help you.
Upvotes: 1