Reputation: 11
I am trying to create a multipart upload request from C# to upload a small file to Google Drive as per https://developers.google.com/drive/v3/web/multipart-upload
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", access_token);
//api endpoint
var apiUri = new Uri("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart");
// read the image content
var imageBinaryContent = new ByteArrayContent(fileBytes);
imageBinaryContent.Headers.Add("Content-Type", "image/jpeg");
// prepare the metadata content
string metaContent = "{\"name\":\"myObject\"}";
byte[] byteArray = Encoding.UTF8.GetBytes(metaContent);
var metaStream = new ByteArrayContent(byteArray);
metaStream.Headers.Add("Content-Type", "application/json; charset=UTF-8");
// create the multipartformdata content, set the headers, and add the above content
var multipartContent = new MultipartFormDataContent();
multipartContent.Headers.Remove("Content-Type");
multipartContent.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundry=myboundry---");
multipartContent.Add(metaStream);
multipartContent.Add(imageBinaryContent);
HttpResponseMessage result = await client.PostAsync(apiUri, multipartContent);
}
But I can't seem to get it working. This code works fine for simple uploads to Drive:
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", access_token);
//api endpoint
var apiUri = new Uri("https://www.googleapis.com/upload/drive/v3/files?uploadType=media");
// read the image content
var imageBinaryContent = new ByteArrayContent(fileBytes);
imageBinaryContent.Headers.Add("Content-Type", "image/jpeg");
HttpResponseMessage result = await client.PostAsync(apiUri, imageBinaryContent);
}
Upvotes: 1
Views: 979
Reputation: 1
I had the same problem and it was because of incorrect boundary separation between each form part.
Problem 1 : Misspelled / malformed boundary declaration in header:
Instead of using:
multipartContent.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundry=myboundry---");
Do the following:
multipartContent.Headers.TryAddWithoutValidation("Content-Type", "multipart/related; boundary=myboundry");
Problem 2 : Missing MultipartFormDataContent part seperation:
Instead of using:
var multipartContent = new MultipartFormDataContent();
multipartContent.Add(metaStream);
multipartContent.Add(imageBinaryContent);
Do the following:
var multipartContent = new MultipartFormDataContent("myboundry");
multipartContent.Add(metaStream, "myboundry");
multipartContent.Add(imageBinaryContent, "myboundry");
Full version after fixes: (works for me when tested)
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", access_token);
//api endpoint
var apiUri = new Uri("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart");
// read the image content
var imageBinaryContent = new ByteArrayContent(fileBytes);
imageBinaryContent.Headers.Add("Content-Type", "image/jpeg");
// prepare the metadata content
string metaContent = "{\"name\":\"myObject\"}";
byte[] byteArray = Encoding.UTF8.GetBytes(metaContent);
var metaStream = new ByteArrayContent(byteArray);
metaStream.Headers.Add("Content-Type", "application/json; charset=UTF-8");
// create the multipartformdata content, set the headers, and add the above content
var multipartContent = new MultipartFormDataContent("myboundry");
multipartContent.Headers.Remove("Content-Type");
multipartContent.Headers.TryAddWithoutValidation("Content-Type", "multipart/related; boundary=myboundry");
multipartContent.Add(metaStream, "myboundry");
multipartContent.Add(imageBinaryContent, "myboundry");
HttpResponseMessage result = await client.PostAsync(apiUri, multipartContent);
}
Upvotes: 0
Reputation: 1151
For those trying this out i .net core, here's my code:
public async Task UploadFile(Stream stream, string filename)
{
var accessToken = "";
using var client = _httpClientFactory.CreateClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var metaContent = JsonContent.Create(new { name = filename });
var streamContent = new StreamContent(stream);
var multipart = new MultipartContent { metaContent, streamContent };
streamContent.Headers.ContentType = new MediaTypeHeaderValue(MediaTypeNames.Application.Octet);
streamContent.Headers.ContentLength = stream.Length;
var result = await client.PostAsync("https://www.googleapis.com/upload/drive/v3/files?uploadtype=multipart", multipart);
}
Upvotes: 1
Reputation: 395
Two things jump out:
boundary
in boundry=myboundry
. Content-Type
is multipart/related
.Upvotes: 1