cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
micpol
Frequent Visitor

A working example of posting an RDL file wanted

I am working on posting a paginated report file into a workspace by means of Power BI REST API -https://docs.microsoft.com/en-us/rest/api/power-bi/imports/postimportingroup. The workspace is associated wth an A4 capacity, so it supports paginated reports. Since I am working on an application for 3rd party customers, the emebed reports approach is applied. This entails that an access token is retrieved basing on a client ID/secret and it is used then for communication over with Power BI service by the REST API.

 

While I am uploading a PBIX file no error is faced, however when I switch to a RDL file, I got this error:

 

"error":{"code":"RequestedFileIsEncryptedOrCorrupted","pbi.error":{"code":"RequestedFileIsEncryptedOrCorrupted","parameters":[],"details":[],"exceptionCulprit":1}}}

 

The URL, headers and body (I created an empty report for this test) look as below:

 

https://api.powerbi.com/v1.0/myorg/groups/[removed]/imports?datasetDisplayName=Paginated&nameConflict=Abort

Authorization: "Bearer [removed]"
Content-Type: "multipart/form-data; boundary=bbd44c43bfdb666aae510c2963f1f58a7df6f20172ee69c494ab549df1bf"

--bbd44c43bfdb666aae510c2963f1f58a7df6f20172ee69c494ab549df1bf
Content-Disposition: form-data; name="file"; filename="blank.rdl"
Content-Type: application/rdl

<?xml version="1.0" encoding="utf-8"?>
<Report MustUnderstand="df" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns:df="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition/defaultfontfamily">
<rd:ReportUnitType>Mm</rd:ReportUnitType>
<rd:ReportID>852f90cd-e634-4063-9524-ee42e4b14caf</rd:ReportID>
<df:DefaultFontFamily>Segoe UI</df:DefaultFontFamily>
<AutoRefresh>0</AutoRefresh>
<ReportSections>
<ReportSection>
<Body>
<ReportItems>
<Textbox Name="ReportTitle">
<rd:WatermarkTextbox>Title</rd:WatermarkTextbox>
<rd:DefaultName>ReportTitle</rd:DefaultName>
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value />
<Style>
<FontFamily>Segoe UI Light</FontFamily>
<FontSize>28pt</FontSize>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<Top>0mm</Top>
<Height>12.7mm</Height>
<Width>139.7mm</Width>
<Style>
<Border>
<Style>None</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</ReportItems>
<Height>57.15mm</Height>
<Style>
<Border>
<Style>None</Style>
</Border>
</Style>
</Body>
<Width>152.4mm</Width>
<Page>
<PageFooter>
<Height>11.43mm</Height>
<PrintOnFirstPage>true</PrintOnFirstPage>
<PrintOnLastPage>true</PrintOnLastPage>
<ReportItems>
<Textbox Name="ExecutionTime">
<rd:DefaultName>ExecutionTime</rd:DefaultName>
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Globals!ExecutionTime</Value>
<Style />
</TextRun>
</TextRuns>
<Style>
<TextAlign>Right</TextAlign>
</Style>
</Paragraph>
</Paragraphs>
<Top>5.08mm</Top>
<Left>101.6mm</Left>
<Height>6.35mm</Height>
<Width>50.8mm</Width>
<Style>
<Border>
<Style>None</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</ReportItems>
<Style>
<Border>
<Style>None</Style>
</Border>
</Style>
</PageFooter>
<PageHeight>29.7cm</PageHeight>
<PageWidth>21cm</PageWidth>
<LeftMargin>2cm</LeftMargin>
<RightMargin>2cm</RightMargin>
<TopMargin>2cm</TopMargin>
<BottomMargin>2cm</BottomMargin>
<ColumnSpacing>0.13cm</ColumnSpacing>
<Style />
</Page>
</ReportSection>
</ReportSections>
<ReportParametersLayout>
<GridLayoutDefinition>
<NumberOfColumns>4</NumberOfColumns>
<NumberOfRows>2</NumberOfRows>
</GridLayoutDefinition>
</ReportParametersLayout>
</Report>
--bbd44c43bfdb666aae510c2963f1f58a7df6f20172ee69c494ab549df1bf--

 

Does anyone have a working dump of of HTTP headers and body enabling to upload an RDL file successfuly into the Power BI serivce? I am coding this stuff in GO, hence the HTTP level fits me best.

 

I have also tried to use a PowerShell approach which I have found in Internet resources:

 

function Publish-PowerBIImport {

param (
[string]$Path,
[string]$GroupId
)

$powerBiBodyTemplate =
@'
--{0}
Content-Disposition: form-data; name="file"; filename="{1}"
Content-Type: application/rdl

{2}
--{0}--

'@

$fileName = [IO.Path]::GetFileName($Path)
$boundary = [guid]::NewGuid().ToString()
$fileBytes = [System.IO.File]::ReadAllBytes($Path)
$encoding = [System.Text.Encoding]::GetEncoding("utf-8")
$filebody = $encoding.GetString($fileBytes)
$body = $powerBiBodyTemplate -f $boundary, $fileName, $encoding.GetString($fileBytes)
$headers = @{
"Authorization" = "Bearer [removed]"
}

$url = "https://api.powerbi.com/v1.0/myorg/groups/$GroupId/imports?datasetDisplayName=$fileName&nameConflict=Abort"

Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $body -ContentType "multipart/form-data; boundary=--$boundary"

}

$groupId = "[removed]"
$id = Publish-PowerBIImport -GroupId $groupId -Path "./file.rdl"

 
It work better, as the content seems to be processed. To confirm that I stopped the capacity for a while:
 
Invoke-RestMethod : {"error":{"code":"PaginatedReportCapacityStoppedOrNotFound","pbi.error":{"code":"PaginatedReportCapacityStoppedOrNotFound","parameters":{},"details":[{"code":"capacityObjectId","detail":{"type":1,"value":"[removed]"}}],"exceptionCulprit":1}}}

 

However, after restarting it, I got another UnknownError:

 

Invoke-RestMethod : {"error":{"code":"UnknownError","pbi.error":{"code":"UnknownError","parameters":{},"details":[],"exceptionCulprit":1}}}

 

Perhaps this means that the file data sent by the GO program is malformed.

 

I have also given a try to C#:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
//Install-Package Microsoft.PowerBI.Api
using Microsoft.PowerBI.Api;
using Microsoft.PowerBI.Api.Models;
using System.IO;
using System.Threading;
using Microsoft.Rest;
namespace importPbix_PBIE

{
class Program
{
static string workspaceCollectionName = "Paginated";
static string workspaceId = "[removed]";
static string filePath = @"./blank.rdl";
static string accessToken = "[removed]";
static void Main(string[] args)
{
var credentials = new TokenCredentials(accessToken, "Bearer");
var client = new PowerBIClient(new Uri($"{"https://api.powerbi.com"}"), credentials);
using (var file = File.Open(filePath, FileMode.Open))
{
try {
var import = client.Imports.PostImportWithFileInGroup(new Guid(workspaceId), file, workspaceCollectionName, "Abort");
Console.WriteLine("{0}", import);
}
catch(Microsoft.Rest.HttpOperationException e) {
Console.WriteLine("{0} {1}",
e.Response.Content,
e.Response.StatusCode);
}
while (true) ;
}
}
}
}

 

unfortunatelly, the result is the same as in case of the 1st program in GO:

 

{"error":{"code":"RequestedFileIsEncryptedOrCorrupted","pbi.error":{"code":"RequestedFileIsEncryptedOrCorrupted","parameters":{},"details":[],"exceptionCulprit":1}}} BadRequest

 

A working HTTP flow or any ideas would be appreciated.

 

--

Michal

 

2 REPLIES 2
fandrusi
New Member

Update: I returned to this issue and the import is working without error!  I'm using the C# POST.  Part of my issue was I'm POSTing an RDL and the only acceptable conflict" param values are "Abort" and "Overwrite", this isn't obvious in all instances of the docu, but it is there.  Passing something else returns a non-specific error.

 

(Aside: Unfortunately there's no good "Upsert" option, you have to know if the file exists in the destination directory before you make the call.)

 

In the OP C# example the problem might be the file isn't be passed in the proper format.  In my situation I'm GETting an RDL then POSTing it back.  I GET the file from azure source workspace into a string to manipulate it then POST it.

 

The wrapper client call will package the file in the proper Form-Data structure for the Rest call.

 

This C# works (GET then POST)

 

string localRdl

HttpOperationResponse<Stream> getResponse = await client.Reports.ExportReportInGroupWithHttpMessagesAsync([workspace Id], [report Id]);

if (getResponse.Response.StatusCode == HttpStatusCode.OK)
{
    var stream = getResponse.Response.Content.ReadAsStreamAsync();

    StreamReader reader = new StreamReader(stream.Result);
    localRdl = reader.ReadToEnd();
}

...
...

MemoryStream ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(localRdl));

HttpOperationResponse<Import> postResponse = await client.Imports.PostImportFileWithHttpMessage([Workspace ID], ms, [report name], "Abort");

if (postResponse.Response.StatusCode == HttpStatusCode.Accepted)
{
    /* all good */
}

 

fandrusi
New Member

Having the identical problem.   It's odd that there's a PowerBI client which makes it very easy to pull down .RDLs but submitting them feels nearly impossible.  I figure there must be a wrapper for the content prep somplace, otherwise it's pretty difficult to deal with.

Helpful resources

Announcements
PBI_User Group Leader_768x460.jpg

Manage your user group events

Check out the News & Announcements to learn more.

MBAS on Demand

2021 Release Wave 2 Plan

Power Platform release plan for the 2021 release wave 2 describes all new features releasing from October 2021 through March 2022.

Get Ready for Power BI Dev Camp

Microsoft named a Leader in The Forrester Wave

Microsoft received the highest score of any vendor in both the strategy and current offering categories.

R2 (Green) 768 x 460px.png

Microsoft Dynamics 365 & Power Platform User Professionals

DynamicsCon is a FREE, 4 half-day virtual learning experience for 11,000+ Microsoft Business Application users and professionals.