Due to the fact that HttpWebRequest is obsolete I'm in the process of upgrading to the equivalent in .NET 6.
I'm not understanding why I'm getting a 401 unauthorized. I can get the bearer token successfully but I just can't seem to find the right combination to successfully upload the file.
private static async Task UploadCsvFileAsync(string authToken)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://subdomain.domain.com/");
client.DefaultRequestHeaders
.Accept
.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
using (var request = new HttpRequestMessage())
{
request.RequestUri = new Uri(uploadUrl);
request.Method = HttpMethod.Post;
request.Headers.Add("api-version", "1");
request.Headers.Add("Authorization", $"Bearer {authToken}");
string header = $"{Environment.NewLine}--{formBoundary}{Environment.NewLine}" +
$"Content-Disposition: form-data; name=\"csvfile\"; filename=\"{csvFileName}\"{Environment.NewLine}" +
$"Content-Type: text/csv{Environment.NewLine}{Environment.NewLine}";
byte[] headerBytes = Encoding.UTF8.GetBytes(header);
var headerContent = new StreamContent(new MemoryStream(headerBytes));
headerContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
var content = new MultipartFormDataContent();
content.Add(headerContent, "metadata", csvFileName);
var response = await client.PostAsync(uploadUrl, content);
// the response code is 401 - Unauthorized
}
}
}
I have working .NET Framework 4.x code working. Since we're migrating our code to .NET 6 it has to be re-written.
Obviously I'm doing something wrong - I just can't seem to figure out what I'm missing.
Any help is greatly appreciated. Thank you in advance.
Edit: 03/29/2023 - including correct code as provided by answer below.
private static async Task UploadCsvFileAsyncV2(string authToken)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(uploadUrl);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
client.DefaultRequestHeaders
.Accept
.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
using (var request = new HttpRequestMessage(HttpMethod.Post, "uploads"))
{
request.Headers.Add("api-version", "1");
string header = $"{Environment.NewLine}--{formBoundary}{Environment.NewLine}" +
$"Content-Disposition: form-data; name=\"csvfile\"; filename=\"{csvFileName}\"{Environment.NewLine}" +
$"Content-Type: text/csv{Environment.NewLine}{Environment.NewLine}";
byte[] headerBytes = Encoding.UTF8.GetBytes(header);
var headerContent = new StreamContent(new MemoryStream(headerBytes));
headerContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
var content = new MultipartFormDataContent
{
{ headerContent, "metadata", csvFileName }
};
request.Content = content;
var response = await client.SendAsync(request);
}
}
}
You're not using HttpClient
quite right. Notice how you declare the HttpRequestMessage
- where you add the auth header - but never actually use it? You're sort of mixing the old method with the new one and not actually sending out the auth token.
If you want to use HttpRequestMessage
, which is fine, just use HttpClient.SendAsync
and supply the message. Specifically try this after byte[] headerBytes = Encoding.UTF8.GetBytes(header);
:
request.Headers.Add("Content-Type", "application/octet-stream");
var content = new MultipartFormDataContent();
content.Add(new StreamContent(new MemoryStream(headerBytes)), "metadata", csvFileName);
request.Content = content;
var response = await client.SendAsync(request);