我尝试通过网络请求对Google进行分段上传,并且我已经关注如何构建有效的多部分文件上传请求Google's instructions,以便我可以发送元数据和实际的文件数据同时存在,但我在多部分体中得到了一个"缺少结束边界。"当我尝试上传文件时出错,并且出于对原因的想法。我做错了什么?
另外,我没有使用Drive SDK,因为它不符合我的需求。
这是我的代码:
public bool WriteFileData(Stream data, DSFile file, DSUser user)
{
var parent = new Parent();
var folders = GetUserFolders(user, false);
DSFolder parentFolder = folders.Where(f => f.FullPath == file.VirtualPath).FirstOrDefault();
parent.Id = parentFolder.DepositoryFolderId;
var addFileRequest = new AddFileRequest();
addFileRequest.Parents.Add(parent);
addFileRequest.Title = (file.FileName.ToLower().Contains(".ext") == false) ? file.FileName + ".ext" : file.FileName;
addFileRequest.ModifiedDate = ServiceUtil.ToISO8601(DateTime.Now);
addFileRequest.MimeType = "application/octet-stream";
addFileRequest.WritersCanShare = false;
addFileRequest.Description = file.Description;
addFileRequest.Labels = new FileLabels();
byte[] binData = new byte[data.Length];
data.Read(binData, 0, (int)data.Length);
string metadata = Microsoft.Http.HttpContentExtensions.CreateJsonDataContract<AddFileRequest>(addFileRequest).ReadAsString();
string binData64 = Convert.ToBase64String(binData);
string contentString = "--123ABC Content-Type: application/json; charset=UTF-8 " + metadata;
contentString += "--123ABC Content-Type: application/octet-stream " + binData64;
contentString += " --123ABC--";
HttpResponseMessage response;
try
{
HttpClient client = new HttpClient();
AddAuthHeader(client, credential.AccessToken);
client.DefaultHeaders.ContentType = "multipart/related; boundary=\"123ABC\"";
client.DefaultHeaders.ContentLength = HttpContent.Create(contentString).ReadAsByteArray().Length;
response = client.Post("https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart", HttpContent.Create(contentString));
string responseText = response.Content.ReadAsString();
return false;
}
catch (Exception ex)
{
return false;
}
}
编辑:这是我对AddFileRequest的定义:
[DataContract]
public class AddFileRequest
{
[DataMember(Name="title")]
public string Title { get; set; }
[DataMember(Name = "labels")]
public FileLabels Labels { get; set; }
[DataMember(Name = "mimeType")]
public string MimeType { get; set; }
[DataMember(Name = "modifiedDate")]
public string ModifiedDate { get; set; }
[DataMember(Name = "parents")]
public List<Parent> Parents { get; set; }
[DataMember(Name = "description")]
public string Description { get; set; }
[DataMember(Name="writersCanShare")]
public bool WritersCanShare { get; set; }
}
答案 0 :(得分:0)
找到解决方案。我决定在对象浏览器周围进行操作,并注意到System.Net.Http命名空间有一个&#34; MultipartFormDataContent&#34; 类来完成这个操作。之前我没有看到它,因为由于某种原因,有两组不同的几乎相同(但不兼容)的HTTP命名空间:Microsoft.Http和System.Net.Http。以下是有效的更新代码:
public bool WriteFileData(Stream data, DSFile file, DSUser user)
{
var parent = new Parent();
var folders = GetUserFolders(user, false);
DSFolder parentFolder = folders.Where(f => f.FullPath == file.VirtualPath).FirstOrDefault();
parent.Id = parentFolder.DepositoryFolderId;
var addFileRequest = new AddFileRequest();
addFileRequest.Parents.Add(parent);
addFileRequest.Title = (file.FileName.ToLower().Contains(".ext") == false) ? file.FileName + ".ext" : file.FileName;
addFileRequest.ModifiedDate = ServiceUtil.ToISO8601(DateTime.Now);
addFileRequest.MimeType = "application/octet-stream";
addFileRequest.WritersCanShare = false;
addFileRequest.Description = file.Description;
addFileRequest.Labels = new FileLabels();
string metadata = Microsoft.Http.HttpContentExtensions.CreateJsonDataContract<AddFileRequest>(addFileRequest).ReadAsString();
var content = new System.Net.Http.MultipartFormDataContent("ABC123");
content.Add(new System.Net.Http.StringContent(metadata, System.Text.Encoding.UTF8, "application/json"));
content.Add(new System.Net.Http.StreamContent(data));
try
{
var client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", credential.AccessToken);
var response = client.PostAsync("https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart", content).Result;
string responseText = response.Content.ReadAsStringAsync().Result;
return false;
}
catch (Exception ex)
{
return false;
}
}