iim*_*nov 0 c# google-drive-api
尝试使用/upload端点解决将文件上传到 Google Drive 的问题时遇到了一些麻烦。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);
Run Code Online (Sandbox Code Playgroud)
我记录以下请求:
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 }
Run Code Online (Sandbox Code Playgroud)
具有以下请求内容(经过修饰):
--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--
Run Code Online (Sandbox Code Playgroud)
我花了一整天的时间来解决这个问题,它让我走到了这一步。我有预感这个问题很愚蠢,但我就是想不通。
有人可以把目光投向这个问题,也许你能发现我在哪里犯了一个错误,这会很有帮助吗?
###ref: 发送分段上传请求
感谢@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);
Run Code Online (Sandbox Code Playgroud)
请注意,通常会添加文件名和内容类型作为其中的一部分,StreamContent但 Google Drive API 会忽略这些标头。这是故意这样做的,因为 API 期望接收具有相关属性的元数据对象。(以下标头已从上面的代码示例中删除,但将保留在此处以供将来参考)
streamContent.Headers.ContentDisposition.FileName = "\"" + fileName + "\"";
streamContent.Headers.ContentType = new MediaTypeHeaderValue(fileType);
Run Code Online (Sandbox Code Playgroud)
请注意"parents":["{folder_id}"],如果您想将文件上传到 Google Drive 中的子文件夹,则只需指定属性。
希望这对将来的其他人有帮助。
| 归档时间: |
|
| 查看次数: |
4566 次 |
| 最近记录: |