c# - 如何发送 Microsoft Graph 上传 session 的最终字节?

标签 c# azure file-upload microsoft-graph-api

我正在遵循 Microsoft 提供的有关将大文件上传到 Microsoft Graph 的文档。
除了文件最后字节上的字节数组之外,一切都运行良好。

https://learn.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");
}

这工作正常,所以现在我开始上传文件。 同样,一切正常,直到最后一个字节[]。

我已经验证最终 byte[] 的预期范围与我发送的字节数组匹配。

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 中保存一些文件。

最佳答案

问题原来是我两次设置了内容长度 header ,其中一次使用了错误的值。只需注释掉以下行,上面的所有内容都会正常工作。

//request.ContentLength = buffer.Length;

最终上传时,长度不是缓冲区的完整长度,而是需要设置为 bytesRead。

关于c# - 如何发送 Microsoft Graph 上传 session 的最终字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70311640/

相关文章:

azure - 如何更改 sidecarject-config.yaml 中的 istio 全局参数

git - 如何解决 azure 环境中 pull 请求批准的冲突

django - 如何在 django 管理中将多个图像上传与 UPLOADIFY 集成?

python - 通过DDP上传文件到Meteor

node.js - 在 Express 包装的 Azure NextJs 应用程序上部署后,应用程序将永久加载

html - 如何在 IE8 中垂直对齐文件输入的文件名

c# - 在 Entity Framework 6 中使用来自多个线程的单个上下文

java - 请解释为什么在 Cpp、Java 和 C# 中允许或不允许将 List<A> 转换为 List<A.super>

c# - 在 ASP.NET MVC 应用程序中保存配置信息的最佳实践在哪里?

c# - 将具有双属性的对象列表与 FluentAssertions 进行比较 (C#)