Forum Discussion
API Import 400 Bad Request Error when uploading pbix file
- 9 years ago
For new reports just remove the name conflict parameter
Anonymous
I see you are appending the nameConflict parameter to the URL, one most probably reason I can think of for your 400 error is that the url with nameConflict parameter would throw error if the report you'd like to import doesn't already exist.
https://api.powerbi.com/v1.0/myorg/imports?datasetDisplayName=TestImport&nameConflict=Overwrite
By the way, I don't find /groups/{groupid} in the URL. Do note the that you can only embed the reports from a created app workspace.
For better troubleshooting, I'd suggest you add an extra catch block.
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
}
}
}
}
Also you can reference my import pbix file demo.
using System;
using System.Net;
//Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory -Version 2.21.301221612
using Microsoft.IdentityModel.Clients.ActiveDirectory;
//Install-Package Newtonsoft.Json
using Newtonsoft.Json;
using System.IO;
using System.Threading.Tasks;
namespace ConsoleApplication39
{
class Program
{
//Step 1 - Replace {client id} with your client app ID.
//To learn how to get a client app ID, see Register a client app (https://msdn.microsoft.com/en-US/library/dn877542.aspx#clientID)
private static string clientID = "{client id}";
//Resource Uri for Power BI API
private static string resourceUri = "https://analysis.windows.net/powerbi/api";
//OAuth2 authority Uri
private static string authorityUri = "https://login.windows.net/common/oauth2/authorize";
private static string token = String.Empty;
//Uri for Power BI datasets
private static string pbiEndpoint = "https://api.powerbi.com/v1.0/myorg";
//Example dataset name and group name
private static string groupId = "{group id}";
static void Main(string[] args)
{
//Import sample
string pbixPath = @"C:\test\KPI.pbix";
string datasetDisplayName = "mydataset";
Task t = Import(string.Format("{0}/groups/{1}/imports?datasetDisplayName={2}&nameConflict=Overwrite", pbiEndpoint, groupId, datasetDisplayName), pbixPath);
t.Wait();
Console.ReadKey();
}
public static async Task<string> Import(string url, string fileName)
{
string responseStatusCode = string.Empty;
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
request.KeepAlive = true;
var credential = new UserCredential(yourPbiAccount, Password);
// Authenticate using created credentials
var authenticationContext = new AuthenticationContext(authorityUri);
var authenticationResult = await authenticationContext.AcquireTokenAsync(resourceUri, clientID, credential);
token = authenticationResult.AccessToken;
request.Headers.Add("Authorization", String.Format("Bearer {0}", token.ToString()));
using (Stream rs = request.GetRequestStream())
{
rs.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; filename=\"{0}\"\r\nContent-Type: application / octet - stream\r\n\r\n";
string header = string.Format(headerTemplate, fileName);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes, 0, headerbytes.Length);
using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, bytesRead);
}
}
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
rs.Write(trailer, 0, trailer.Length);
}
try
{
using (HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse)
{
responseStatusCode = response.StatusCode.ToString();
Console.WriteLine("Import pbix file is {0}", responseStatusCode);
}
}
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 responseStatusCode;
}
}
}
When I try to upload a file that previously exists using the URL with ?datasetDisplayName={2}&nameConflict=Overwrite at the end, it works great. However when the report is a new report, and I try to upload it using...
https://api.powerbi.com/v1.0/myorg/groups/{GroupID}/imports
It does not update. In the code that you gave me to catch the error, all I see is the word Message: "". It does not tell me anything more. Previously you said that if you try to import a report, that does not exist, and use the ?datasetDisplayName={2}&nameConflict=Overwrite at end of URL, that it will not work. Well it seems even without that it does not work. Any thoughts why?
Thanks,
Stizz001
- brenkehoe9 years agoHelper I
For new reports just remove the name conflict parameter
- Anonymous9 years agoNot applicableYea, i ended up figuring that out late today. Sorry for not updating the thread. I appreciate all your help. I wpuld have struggled a lot more than I did without it.
- ddavid8 years agoNew Member
Hi Anonymous ,
I am getting <Response [400]>, when I run this code. Any idea what is wrong ?
Thanks in advance.
import requests
values = """
-----BOUNDARY
Content-Disposition: form-data; name="mypbix"; filename="mypbix.pbix"
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
{PBIX binary data}
-----BOUNDARY"""
headers = {
'Content-Type': 'multipart/form-data; boundary=---BOUNDARY',
'Authorization': 'Bearer <access_token>'
}
request = requests.post('https://api.powerbi.com/v1.0/myorg/groups/<group_id>/imports?datasetDisplayName=ProductOrder', data=values, headers=headers)