Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
rbroida
Helper I
Helper I

Failing: CloneTileInGroupAsync() in .NET API v2

We are writing a C# application to automate the creation of datasets for specific customers in a Power BI Embedded Capacity (v2). We are using latest versions of the following Nuget packages: Microsoft.PowerBI.API (v4.2.0) ("REST API Library") and Microsoft.AnalysisServices.NetCore.retail.amd64 (v.19.32.0) ("TOM API Library"). We authenticate our API calls with access tokens issued to an AAD Service Principal which, as far as we know, has all necessary permissions in Power BI.

We are able to:

  1. Create a unique workspace for the customer (using REST API Library)
  2. Create a unique data source for the customer in a shared on-premise data gateway (using REST API Library)
  3. Copy a "master" dataset into the customer's workspace (using TOM API Library)
  4. Bind the customer's copy of the dataset to the customer's data source in the on-premise gateway (using REST API Library)
  5. Refresh the customer's copy of the dataset (using REST API Library)
  6. Copy reports into the customer's workspace (using REST API Library)
  7. Create a dashboard in the customer's workspace (using REST API Library)

But we get a 401 Unauthorized when we try to clone tiles from a "master" dashboard into the customer's dashboard. We call Dashboards.CloneTileInGroupAsync() with what we believe are the correct parameters. Here is the code:

var cloneRequest = new CloneTileRequest
{
TargetDashboardId = newDashboard.Id,
TargetWorkspaceId = targetWorkspaceId,
TargetReportId = targetReport.Id
};
try
{
await client.Dashboards.CloneTileInGroupAsync(
sourceWorkspaceId,
sourceDashboard.Id,
sourceTile.Id,
cloneRequest);
}

It throws Exception: 401 Unauthorized. We receive no other information about what caused the failure.

 

Our AAD Service Principal has the Power BI ReadWrite.All permission, and it can do the other things mentioned above. The service principal has the Administrator role in both the source workspace and the target workspace.

 

How do we make this work?

 

1 ACCEPTED SOLUTION
rbroida
Helper I
Helper I

Three weeks after I opened a support ticket on this, it finally got transfered to a team with REST API expertise. And they found the solution. When constructing a CloneTIleRequest object, we need to omit the target workspace id, and instead we need to include the target dataset id (which the class calls the "model ID"). So the object declaration should be:

 

var cloneRequest = new CloneTileRequest
{
TargetDashboardId = newDashboard.Id,
TargetReportId = targetReport.Id,

TargetModelId = targetReport.DatasetId
};

 

In my opinion the API documentation on this is incorrect. It says: “targetModelId - string - Optional. A parameter for specifying a target model ID. When cloning a tile linked to a dataset, pass the target model ID to rebind the new tile to a different dataset.” This implies that the parameter should not be sent if a tile is linked to a report not a dataset. Our support ticket would have been unnecessary if the documentation had described the purpose of this parameter correctly. See Dashboards - Clone Tile - REST API (Power BI Power BI REST APIs) | Microsoft Docs

 

I appreciate Microsoft support for showing us how to solve this. I wish Power BI REST APIs were better documented. And I really wish customers could get more usefull diagnostic information with API calls fail.

View solution in original post

11 REPLIES 11
rbroida
Helper I
Helper I

Three weeks after I opened a support ticket on this, it finally got transfered to a team with REST API expertise. And they found the solution. When constructing a CloneTIleRequest object, we need to omit the target workspace id, and instead we need to include the target dataset id (which the class calls the "model ID"). So the object declaration should be:

 

var cloneRequest = new CloneTileRequest
{
TargetDashboardId = newDashboard.Id,
TargetReportId = targetReport.Id,

TargetModelId = targetReport.DatasetId
};

 

In my opinion the API documentation on this is incorrect. It says: “targetModelId - string - Optional. A parameter for specifying a target model ID. When cloning a tile linked to a dataset, pass the target model ID to rebind the new tile to a different dataset.” This implies that the parameter should not be sent if a tile is linked to a report not a dataset. Our support ticket would have been unnecessary if the documentation had described the purpose of this parameter correctly. See Dashboards - Clone Tile - REST API (Power BI Power BI REST APIs) | Microsoft Docs

 

I appreciate Microsoft support for showing us how to solve this. I wish Power BI REST APIs were better documented. And I really wish customers could get more usefull diagnostic information with API calls fail.

rbroida
Helper I
Helper I

Liang,

 

We've now put the service principal directly into the Administrators role in the source workspace, and it continues to be an Administrator in the target workspace. We still get the same error.

 

Since you say our code looks correct, this appears to be a bug in the .NET Microsoft.PowerBI.API library. Perhaps it's a bug in the underlying REST API. Or the documentation may be incorrect or incomplete.

 

Can someone from Microsoft monitor our API calls and tell us exactly what is happening? As I said, the only information we get is an exception that says "Unauthorized". We tried calling Dashboards.CloneTileInGroupWithHttpMessagesAsync() but it just returns null. The inability to get detailed error information is one of our big frustrations trying to use the REST API from C#.

V-lianl-msft
Community Support
Community Support

Hi @rbroida ,


It seems everything is set up correctly according to your description. Some suggestions are as follows.

1. Add the Service Principal as an admin in the workspace directly rather than add the security group.

Please refer to article 5 in embed-service-principal#get-started-with-a-service-principal. We should use the Object ID.

2. The Service Principal inherit permission from the tenant rather than the Azure App permissions. 

>>>Service principals inherit the permissions for all Power BI tenant settings from their security group. To restrict permissions create a dedicated security group for service principals and add it to the 'Except specific security groups' list for the relevant, enabled Power BI settings.


Best Regards,
Liang
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Lianl,

It's been 25 days since I posted the issue on this forum, and no one has offered any answer. I opened a support ticket, but the Power BI support team seems to know nothing about REST APIs. I am extremely disappointed that no one from Microsoft seems to be helping us resolve this. Could you please give me some reply?

Liang,

 

It's been a week and I haven't heard anything more from you or anyone else at Microsoft. The issue is still not resolved. Can you offer any more help?

Liang,

1. The service principal creates the target workspace (by calling the REST API, as stated above), so it is already an admin of the target workspace. The service principal is not an admin of the source workspace, but it belongs to a security group that is an admin of the source workspace. Why would Dashboards.CloneTileInGroupAsync() require this when it's not required by any of the other REST APIs we're calling? For instance, Reports.CloneReportInGroupAsync() doesn't require the service principal to be an adminstrator in the source workspace as long as it belongs to a security group that's an administrator in the source workspace.

2. We did this, and it didn't fix the problem.

lbendlin
Super User
Super User

If you have a Pro license you can consider raising a Pro ticket at https://powerbi.microsoft.com/en-us/support/pro/

Ibendlin,

Thank you. I've opened a support ticket but I'm not sure if they'll help me. My initial contact person said she only works on "break/fix issues", and I have no idea if that's what this is.

Tell her you want the ticket forwarded to the next level.  It may take a while but so far all our tickets have eventually been resolved.  You have leverage because only you can allow the ticket to be closed.

She said today that "her team" doesn't know anything about REST APIs or client libraries for them. I asked if she could please find someone who does.

I still haven't gotten any answer on my support ticket. The team handling the ticket seems to have no clue about REST APIs, and they haven't been able or willing to turn it over to a team with the right expertise. This is highly frustrating.

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.