Hello,
I am attempting to access the Business Central API from a C# application. The program successfully connects to BC and gets a token, but the request using that token fails with StatusCode: 401, ReasonPhrase: 'Unauthorized'.
This process works fine in Postman, and if I copy the token from the working Postman and paste it into the C# code, the API request works fine. The token retrieved from BC appears to be much shorter than the one that is obtained in Postman.
I'm guessing it's something simple I am missing, but I can find what that might be.
Here is my code.
static async Task RunApiTest()
{
try
{
string bearerToken = "";
string ClientId = "(removed)";
string ClientSecret = "(removed)";
string TenantId = "(removed)";
string tokenUrl = $"https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token";
HttpClient client = new HttpClient();
var content = new StringContent("grant_type=client_credentials" +
"&scope=https://api.businesscentral.dynamics.com/.default" +
"&client_id=" + HttpUtility.UrlEncode(ClientId) +
"&client_secret=" + HttpUtility.UrlEncode(ClientSecret));
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
var response = await client.PostAsync(tokenUrl, content);
if (response.IsSuccessStatusCode)
{
var tokenContent = await response.Content.ReadAsStringAsync();
var tokenResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<TokenResponse>(tokenContent);
bearerToken = tokenResponse.AccessToken;
string apiUrl = $"https://api.businesscentral.dynamics.com/v2.0/(removed)/Sandbox/api/v2.0/companies((removed))/customers";
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + bearerToken);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var apiRespponse = await httpClient.GetAsync(apiUrl);
if (apiRespponse.IsSuccessStatusCode)
{
string resultString = await httpClient.GetStringAsync(apiUrl);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
public class TokenResponse
{
[Newtonsoft.Json.JsonProperty("access_token")]
public string AccessToken { get; set; }
}
Thanks!