2 Replies Latest reply on Apr 4, 2017 7:40 AM by Toby Erkson

    Publish workbook with Datasource (tds) file

    Rahul Mishra



      I have created a workbook connecting to a data source (tds) file. I am using Tableau rest api using c# to publish the file to other environments and our database is SQL Server. I am trying to publish in the order below


      1) Publish the datasource .tds file

      2) Update the connection in datasource .tds file

      3) Publish  the packaged workbook .twbx file

      3) Update the packaged workbook .twbx file connection to the datasource .tds file published in step 1 above.


      I am able to successfully publish and update the connection of the datasource .tds file (steps 1 and 2 above). But I get an error during publishing the packaged workbook .twbx file (step 3 above)


      <tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.3.xsd"><error code="400011"><summary>Bad Request</summary><detail>There was a problem publishing the file 'NewDataSourceWB.twbx'.</detail></error></tsResponse>


      I am using the below code to publish. Using the same code I can successfully publish the .twbx file if I use extract or a live connection.


      public HttpResponseMessage PublishWorkbook(string siteId, string projectId, string filePath)




                  string boundry = System.Guid.NewGuid().ToString();



                  XDocument fileUploadDocument = new XDocument(

                      new XElement(XName.Get("tsRequest"),

                          new XElement(XName.Get("workbook"),

                              new XAttribute(XName.Get("name"), Path.GetFileNameWithoutExtension(filePath)),

                              new XAttribute(XName.Get("showTabs"), "false"),

                              new XElement(XName.Get("connectionCredentials"),

                                  new XAttribute(XName.Get("name"), "tableauadmin"),

                                  new XAttribute(XName.Get("password"), "suvoda01!"),

                                  new XAttribute(XName.Get("embed"), "True")),

                              new XElement(XName.Get("project"),

                                  new XAttribute(XName.Get("id"), projectId)))





                  using (MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent(boundry))



                      multipartFormDataContent.Headers.TryAddWithoutValidation("Content-Type", "multipart/mixed; boundary=" + boundry);



                      // add the header

                      StringContent stringContent = new StringContent(fileUploadDocument.ToString(), Encoding.UTF8, "text/xml");

                      stringContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")


                          Name = "\"" + "request_payload" + "\""




                      // stream content

                      FileStream fs = File.OpenRead(filePath);

                      int bytesRead;

                      int fileSize = (int)fs.Length;

                      var buffer = new byte[fileSize];

                      bytesRead = fs.Read(buffer, 0, buffer.Length);



                      Stream stream = new MemoryStream(buffer);

                      StreamContent streamContent = new StreamContent(stream);



                      streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")


                          Name = "\"" + "tableau_workbook" + "\"",

                          FileName = "\"" + Path.GetFileName(filePath) + "\""


                      streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");



                      multipartFormDataContent.Add(streamContent, "file", Path.GetFileName(filePath));



                      HttpResponseMessage httpResponse = null;



                      httpResponse = _httpClient.PostAsync(string.Format("sites/{0}/workbooks", siteId), multipartFormDataContent).Result;



                      return httpResponse;




      Please let me know if I am missing any thing.


      1) I cannot publish a packaged workbook .twbx file connecting to datasource .tds file even though a database with the same name exists on the Tableau server.

      2) Though I can publish a packaged workbook .twbx file using a live connection, I cannot publish the same file as .twb.