I am new to API coding and working on a module which signs in to Tableau Server and gets the list of workbooks stored in a site. The code is to be written in C# using the Tableau Rest API.
I was able to sign in to Tableau server successfully using the Rest API. However, I was not able to query the workbooks. Below is my code.
class Program
{
static HttpClient client = new HttpClient();
public static string site_id { get; set;}
public static string token { get; set; }
static void Main(string[] args)
{
CallWebAPIAsync().Wait();
}
static async Task CallWebAPIAsync()
{
using (var client = new HttpClient())
{
client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
client.BaseAddress = new Uri("https://my server url.com");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream"));
SignIn(client);
Workbooks(client, site_id, token);
}
Console.Read();
}
public class CustomXmlMediaTypeFormatter : XmlMediaTypeFormatter
{
public CustomXmlMediaTypeFormatter()
{
UseXmlSerializer = true;
WriterSettings.OmitXmlDeclaration = false;
}
}
public static tableauCredentialsType SignIn(HttpClient client)
{
var name = "Administrator";
var password = "password";
var site = "";
var tableauCredentialsType = new tsRequest()
{
Item = new tableauCredentialsType
{
name = name,
password = password,
site = new siteType() { contentUrl = site }
}
};
var httpContent = new ObjectContent<tsRequest>(tableauCredentialsType, new CustomXmlMediaTypeFormatter());
var httpResponseMessage = client.PostAsync("/api/3.2/auth/signin", httpContent).Result;
if (httpResponseMessage.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(string.Format("Unable to login to the server", site, name));
var responseLogin = httpResponseMessage.Content.ReadAsAsync<tsResponse>(new List<MediaTypeFormatter>() { new CustomXmlMediaTypeFormatter() }).Result;
var resultTableauCredentialsType = ((tableauCredentialsType)responseLogin.Items[0]);
site_id = resultTableauCredentialsType.site.id;
token = resultTableauCredentialsType.token;
return resultTableauCredentialsType;
}
public static IList<workbookType> Workbooks(HttpClient client, string siteid, string auth_token, int pageSize = 100, int pageNumber =1)
{
IList<workbookType> results = new List<workbookType>();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("x-tableau-auth", auth_token);
var query = client.GetAsync(string.Format("/api/3.2/sites/{0}/workbooks", siteid, pageSize, pageNumber)).Result;
if(query.StatusCode == System.Net.HttpStatusCode.OK)
{
var result = query.Content.ReadAsAsync<tsResponse>(new List<MediaTypeFormatter>() { new CustomXmlMediaTypeFormatter() }).Result;
var pagination = (paginationType)result.Items[0];
var workbooks = ((workbookListType)result.Items[1]).workbook.AsEnumerable();
for (int i=2; i < pageNumber; i++)
{
query = client.GetAsync(string.Format("/api/3.2/sites/{0}/workbooks", siteid, pageSize, i)).Result;
if(query.StatusCode == System.Net.HttpStatusCode.OK)
{
result = query.Content.ReadAsAsync<tsResponse>(new List<MediaTypeFormatter>() { new CustomXmlMediaTypeFormatter() }).Result;
workbooks = workbooks.Concat(((workbookListType)result.Items[1]).workbook.AsEnumerable());
}
}
results = workbooks.ToList();
}
return results;
}
}
When I try to run the Workbooks function in the above code I am getting 401-Unauthorized error. I came to know that I need to pass the X-tableau_auth so that I will have the authentication done while querying for the workbooks. However, I was not able to get that properly.
Can anyone help me with this?