如何发送 Microsoft Graph 上传会话的最后字节?
How do I send the final bytes for a Microsoft Graph Upload Session?
我正在关注 Microsoft 提供的将大文件上传到 Microsoft Graph 的文档。
除了文件最后字节上的字节数组外,一切都很好。
https://docs.microsoft.com/en-us/graph/api/driveitem-createuploadsession?view=graph-rest-1.0
首先,我创建了一个具有文件名的 DriveItem 并上传了一个空字节[]。
using (var emptyFileClient = new HttpClient())
{
var url = "https://graph.microsoft.com/v1.0/drives/" + driveID + "/root:/" + sharepoint2013ID + "/" + fileInfo.Name + ":/content";
emptyFileClient.DefaultRequestHeaders.Add("Authorization", bearer);
var emptyFileContent = new ByteArrayContent(new byte[0]);
var emptyFileResponse = emptyFileClient.PutAsync(url, emptyFileContent).Result;
if (emptyFileResponse.StatusCode != System.Net.HttpStatusCode.Created)
{
return false;
}
}
然后我确保我有一个有效的 DriveItemID
var client = new RestClient("https://graph.microsoft.com/v1.0/drives/" + driveID + "/root:/" + sharepoint2013ID + "/" + fileInfo.Name);
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", bearer);
IRestResponse response = client.Execute(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
return null;
}
接下来我创建一个 UploadSession
//Create UploadSession
var client = new RestClient("https://graph.microsoft.com/v1.0/drives/" + driveID + "/items/" + driveItem.id + "/createUploadSession");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", bearer);
IRestResponse response = client.Execute(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
throw new Exception("Could Not Create Upload Session");
}
这一切正常,所以现在我开始上传文件。
同样,一切正常,直到最后一个字节 [].
我已验证最终字节 [] 的预期范围与我发送的字节数组匹配。
WebRequest request = null;
using (Stream source = File.OpenRead(fileInfo.FullName))
{
double fileSizeBytes = fileInfo.Length;
int bufferSize = 2048000;
byte[] buffer = new byte[bufferSize];
int bytesRead;
var loopCount = 0;
while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
{
double startByte = bufferSize * loopCount;
double endByte = startByte + bytesRead - 1;
var contentRange = "bytes " + startByte + "-" + endByte + "/" + fileSizeBytes;
Console.WriteLine(contentRange);
request = WebRequest.Create(uploadSession.uploadUrl);
request.Headers.Add("Authorization", bearer);
request.Headers.Add("Content-Length", bytesRead.ToString());
request.Headers.Add("Content-Range", contentRange);
request.Method = "PUT";
request.ContentLength = buffer.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(buffer, 0, buffer.Length);
dataStream.Close();
var response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != System.Net.HttpStatusCode.Accepted)
{
return false;
}
loopCount++;
}
}
我一直在测试超过缓冲区大小的大文件,以便将上传分成多个请求。如果减小缓冲区大小,您还可以使用较小的文件进行测试。如有任何帮助,我们将不胜感激。
此外,我对使用 Graph.SDK 或任何其他库不感兴趣,这需要来自网络请求的 运行。这是用于 Sharepoint2013 Server 将在 SharepointOnline 中保存一些文件的混合解决方案。
问题原来是我设置了 content-length header 两次,其中一次使用了不正确的值。只需注释掉以下行,上面的所有内容都会正常工作。
//request.ContentLength = buffer.Length;
在最终上传时,长度不是缓冲区的完整长度,而是需要设置为 bytesRead。
我正在关注 Microsoft 提供的将大文件上传到 Microsoft Graph 的文档。
除了文件最后字节上的字节数组外,一切都很好。
https://docs.microsoft.com/en-us/graph/api/driveitem-createuploadsession?view=graph-rest-1.0
首先,我创建了一个具有文件名的 DriveItem 并上传了一个空字节[]。
using (var emptyFileClient = new HttpClient())
{
var url = "https://graph.microsoft.com/v1.0/drives/" + driveID + "/root:/" + sharepoint2013ID + "/" + fileInfo.Name + ":/content";
emptyFileClient.DefaultRequestHeaders.Add("Authorization", bearer);
var emptyFileContent = new ByteArrayContent(new byte[0]);
var emptyFileResponse = emptyFileClient.PutAsync(url, emptyFileContent).Result;
if (emptyFileResponse.StatusCode != System.Net.HttpStatusCode.Created)
{
return false;
}
}
然后我确保我有一个有效的 DriveItemID
var client = new RestClient("https://graph.microsoft.com/v1.0/drives/" + driveID + "/root:/" + sharepoint2013ID + "/" + fileInfo.Name);
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", bearer);
IRestResponse response = client.Execute(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
return null;
}
接下来我创建一个 UploadSession
//Create UploadSession
var client = new RestClient("https://graph.microsoft.com/v1.0/drives/" + driveID + "/items/" + driveItem.id + "/createUploadSession");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", bearer);
IRestResponse response = client.Execute(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
throw new Exception("Could Not Create Upload Session");
}
这一切正常,所以现在我开始上传文件。 同样,一切正常,直到最后一个字节 [].
我已验证最终字节 [] 的预期范围与我发送的字节数组匹配。
WebRequest request = null;
using (Stream source = File.OpenRead(fileInfo.FullName))
{
double fileSizeBytes = fileInfo.Length;
int bufferSize = 2048000;
byte[] buffer = new byte[bufferSize];
int bytesRead;
var loopCount = 0;
while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
{
double startByte = bufferSize * loopCount;
double endByte = startByte + bytesRead - 1;
var contentRange = "bytes " + startByte + "-" + endByte + "/" + fileSizeBytes;
Console.WriteLine(contentRange);
request = WebRequest.Create(uploadSession.uploadUrl);
request.Headers.Add("Authorization", bearer);
request.Headers.Add("Content-Length", bytesRead.ToString());
request.Headers.Add("Content-Range", contentRange);
request.Method = "PUT";
request.ContentLength = buffer.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(buffer, 0, buffer.Length);
dataStream.Close();
var response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != System.Net.HttpStatusCode.Accepted)
{
return false;
}
loopCount++;
}
}
我一直在测试超过缓冲区大小的大文件,以便将上传分成多个请求。如果减小缓冲区大小,您还可以使用较小的文件进行测试。如有任何帮助,我们将不胜感激。
此外,我对使用 Graph.SDK 或任何其他库不感兴趣,这需要来自网络请求的 运行。这是用于 Sharepoint2013 Server 将在 SharepointOnline 中保存一些文件的混合解决方案。
问题原来是我设置了 content-length header 两次,其中一次使用了不正确的值。只需注释掉以下行,上面的所有内容都会正常工作。
//request.ContentLength = buffer.Length;
在最终上传时,长度不是缓冲区的完整长度,而是需要设置为 bytesRead。