Неправильное составное тело при загрузке файла на Google Диск - PullRequest
0 голосов
/ 22 июня 2019

Попытка решить проблему с загрузкой файлов на Google Диск с помощью конечной точки / upload .Я получаю ошибку Malformed multipart body., даже когда пытаюсь загрузить простой простой текст в виде файла.

Следующий код .net c # используется для создания запроса:

string fileName = "test.txt";
string fileContent = "The quick brown fox jumps over the lazy dog";

var fileStream = GenerateStreamFromString(fileContent); // simple text string to Stream conversion
var streamContent = new StreamContent(fileStream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue("text/plain");

var multiPartFormDataContent = new MultipartFormDataContent("not_so_random_boundary");
// rfc2387 headers with boundary
multiPartFormDataContent.Headers.Remove("Content-Type");
multiPartFormDataContent.Headers.TryAddWithoutValidation("Content-Type", "multipart/related; boundary=" + "not_so_random_boundary");
// metadata part
multiPartFormDataContent.Add(new StringContent("{\"name\":\"" + fileName + "\",\"mimeType\":\"text/plain\",\"parents\":[\"" + folder.id + "\"]}", Encoding.UTF8, "application/json"));
// media part (file)
multiPartFormDataContent.Add(streamContent);

var response_UploadFile = await httpClient.PostAsync(string.Format("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"), multiPartFormDataContent);

Я регистрируюсьследующий запрос:

Method: POST,
RequestUri: 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart',
Version: 1.1,
Content: System.Net.Http.MultipartFormDataContent,
Headers: { Authorization: Bearer /*snip*/ Content-Type: multipart/related; boundary=not_so_random_boundary }

со следующим содержанием запроса (предварительно):

--not_so_random_boundary
Content-Type: application/json; charset=utf-8

Content-Disposition: form-data
{"name":"test.txt","mimeType":"text/plain","parents":["/*snip*/"]}

--not_so_random_boundary
Content-Type: text/plain

Content-Disposition: form-data
The quick brown fox jumps over the lazy dog
--not_so_random_boundary--

Я потратил на это целый день, и это привело меня к этой точке.У меня есть догадка, что эта проблема - что-то глупое, но я просто не могу понять это.

Может ли кто-то бросить на это глаза, возможно, вы обнаружите, где я допустил ошибку, которая была бы очень полезна?

ref:

Отправить многостраничный запрос на загрузку

RFC 2387

Ответы [ 2 ]

1 голос
/ 24 июня 2019

Благодаря предложению @Tanaike мы обнаружили проблему с моим кодом.

Получается, хотя это конкретно не упомянуто в документации (или любых примерах кода), но добавление Content-Disposition: form-data; name="metadata" к StringContent части тела запроса имеет все значение.

Окончательный запрос может быть переписан следующим образом:

// sample file (controlled test example)
string fileName = "test.txt";
string fileType = "text/plain";
string fileContent = "The quick brown fox jumps over the lazy dog";
var fileStream = GenerateStreamFromString(fileContent); // test file

// media part (file)
//var fileStream = File.Open(path_to_file, FileMode.Open, FileAccess.Read); // you should read file from disk
var streamContent = new StreamContent(fileStream);
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
streamContent.Headers.ContentDisposition.Name = "\"file\"";

// metadata part
var stringContent = new StringContent("{\"name\":\"" + fileName + "\",\"mimeType\":\"" + fileType + "\",\"parents\":[\"" + folder.id + "\"]}", Encoding.UTF8, "application/json");
stringContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
stringContent.Headers.ContentDisposition.Name = "\"metadata\"";

var boundary = DataTime.Now.Ticks.ToString(); // or hard code a string like in my previous code
var multiPartFormDataContent = new MultipartFormDataContent(boundary);
// rfc2387 headers with boundary
multiPartFormDataContent.Headers.Remove("Content-Type");
multiPartFormDataContent.Headers.TryAddWithoutValidation("Content-Type", "multipart/related; boundary=" + boundary);
// request body
multiPartFormDataContent.Add(stringContent); // metadata part - must be first part in request body
multiPartFormDataContent.Add(streamContent); // media part - must follow metadata part

var response_UploadFile = await httpClient.PostAsync(string.Format("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"), multiPartFormDataContent);

Обратите внимание , что обычно можно добавить имя файла и тип содержимого как часть StreamContent, но эти заголовки игнорируются Google Drive API. Это сделано намеренно, потому что API ожидает получить объект метаданных с соответствующими свойствами. (следующие примеры были удалены из приведенного выше примера кода, но будут сохранены здесь для дальнейшего использования)

streamContent.Headers.ContentDisposition.FileName = "\"" + fileName + "\"";
streamContent.Headers.ContentType = new MediaTypeHeaderValue(fileType);

Обратите внимание , что вам нужно указать только свойство "parents":["{folder_id}"], если вы хотите загрузить файл в подпапку на Google Диске.

Надеюсь, это поможет кому-то еще в будущем.

1 голос
/ 24 июня 2019

Я думаю, что структура тела запроса для multipart/related может быть неправильной.Так как насчет изменения следующим образом?

Модифицированное тело запроса:

--not_so_random_boundary
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name="metadata"

{"name":"test.txt","mimeType":"text/plain","parents":["/*snip*/"]}
--not_so_random_boundary
Content-Type: text/plain
Content-Disposition: form-data; name="file"

The quick brown fox jumps over the lazy dog
--not_so_random_boundary--
  • Пожалуйста, будьте осторожны, разрывы строк для тела запроса.
  • Пожалуйста, добавьте name для каждой части Content-Disposition.

Примечание:

  • Теперь я могу подтвердить, что при изменении вышеуказанного тела запроса для конечной точки https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart используется как POSTметод, создается текстовый файл test.txt с содержанием The quick brown fox jumps over the lazy dog.

Ссылки:

Если это не сработало, я прошу прощения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...