我们需要根据长度(即4MB)拆分字节数组,并将它们传递给OneDrive API。下面是可工作的版本:
using (var client = new HttpClient())
{
var url = "https://graph.microsoft.com/v1.0" + $"/drives/{driveID}/items/{folderId}:/{originalFileName}:/createUploadSession";
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + GetAccessToken());
var sessionResponse = client.PostAsync(apiUrl, null).Result.Content.ReadAsStringAsync().Result;
byte[] sContents = System.IO.File.ReadAllBytes(filePath);
var uploadSession = JsonConvert.DeserializeObject<UploadSessionResponse>(sessionResponse);
string response = UploadFileBySession(uploadSession.uploadUrl, sContents);
}
UploadFileBySession的代码如下:
private string UploadFileBySession(string url, byte[] file)
{
int fragSize = 1024 * 1024 * 4;
var arrayBatches = ByteArrayIntoBatches(file, fragSize);
int start = 0;
string response = "";
foreach (var byteArray in arrayBatches)
{
int byteArrayLength = byteArray.Length;
var contentRange = " bytes " + start + "-" + (start + (byteArrayLength - 1)) + "/" + file.Length;
using (var client = new HttpClient())
{
var content = new ByteArrayContent(byteArray);
content.Headers.Add("Content-Length", byteArrayLength.ToString());
content.Headers.Add("Content-Range", contentRange);
response = client.PutAsync(url, content).Result.Content.ReadAsStringAsync().Result;
}
start = start + byteArrayLength;
}
return response;
}
internal IEnumerable<byte[]> ByteArrayIntoBatches(byte[] bArray, int intBufforLengt)
{
int bArrayLenght = bArray.Length;
byte[] bReturn = null;
int i = 0;
for (; bArrayLenght > (i + 1) * intBufforLengt; i++)
{
bReturn = new byte[intBufforLengt];
Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLengt);
yield return bReturn;
}
int intBufforLeft = bArrayLenght - i * intBufforLengt;
if (intBufforLeft > 0)
{
bReturn = new byte[intBufforLeft];
Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLeft);
yield return bReturn;
}
}
创建上传会话时反序列化JSON响应的UploadSessionResponse类文件
public class UploadSessionResponse
{
public string odatacontext { get; set; }
public DateTime expirationDateTime { get; set; }
public string[] nextExpectedRanges { get; set; }
public string uploadUrl { get; set; }
}