使用 Microsoft Graph 通用打印 API 上载文档

若要使用 Microsoft Graph 中的通用打印 API 打印文档,你需要 创建一个打印作业、上传文档,然后 启动打印作业。 本文介绍了如何上传文档,首先需要 创建一个上载会话

若要上传文件或文件的一部分,你的应用可以对在 createUploadSession 响应中收到的 uploadUrl 值发出 PUT 请求。 可以上传整个文件,也可以将文件拆分为多个字节范围,只要任意给定请求中的最大字节数小于 10 MB 即可。

可按任意顺序上传文件的片段,并且最多可并行上传四个并发请求。 上传文档的所有二进制片段时,二进制文件将链接到 printDocument

注意:如果应用将文件拆分为多个字节范围,我们建议每个字节范围的大小是 200 KB 的倍数,除非你使用的是 Microsoft Graph SDK,因为这要求区段大小是 320 KB 的倍数。

上传文件

请求

createUploadSession 响应中收到的 uploadUrl 值发出 PUT 请求。

请求标头

名称 说明
Content-Range bytes {startByteIndex}-{endByteIndex}‬/{documentSizeInBytes}。 必填。
Content-Length 需要 {contentLength}。

请求正文

请求正文是一个二进制 blob,其中包含在 Content-Range 标头中指定为 非独占 字节范围的文档的字节数。

示例

PUT https://print.print.microsoft.com/uploadSessions/5400be13-5a4e-4c20-be70-90c85bfe5d6e?tempauthtoken={token}
Content-Range: bytes=0-72796/4533322
Content-Length: 72797

<bytes 0-72796 of the file>

此处的 0 和 72796 是文件段的开始索引和结束索引,而 4533322 则是文档的大小。

响应

当此请求完成时,如果还需要上传其他字节范围,服务器将会返回 202 Accepted 作为响应。

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "expirationDateTime": "2020-10-25T02:19:38.1694207Z",
  "nextExpectedRanges": ["72797-4533321"]
}

应用可以使用 nextExpectedRanges 值来确定开始上传下一字节范围的位置。 可能会发现指定的多个范围,这些范围指明了服务器尚未收到的文件部分。 nextExpectedRanges 属性指示尚未收到的文件的范围,而不是应用应上传文件的方式。

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "expirationDateTime": "2020-10-25T02:19:38.1694207Z",
  "nextExpectedRanges": [
  "72797-72897",
  "78929-4533322"
  ]
}

备注

  • 如果因客户端发送了服务器已接收的片段导致失败,服务器将响应 HTTP 416 Requested Range Not Satisfiable。 可以请求获取上传状态,以获取缺少范围的更详细列表。
  • 在进行 PUT 调用时添加 Authorization 标头可能会导致 HTTP 401 Unauthorized 响应。 授权标头和持有者令牌只应在创建上传会话时发送。 将数据上传到上传会话时,不应将其包含在内。
  • 建议记录 X-MSEdge-Refrequest-id 响应标头(如果存在),以帮助支持团队调查。

完成文件上传

接收文件的最后一个字节范围时,服务器将响应 HTTP 201 Created。 响应正文中还将包括关联 printDocument 的属性集。

请求

PUT https://print.print.microsoft.com/uploadSessions/5400be13-5a4e-4c20-be70-90c85bfe5d6e?tempauthtoken={token}
Content-Length: 10
Content-Range: bytes 4533312-4533321/4533322

<final bytes of the file>

响应

HTTP/1.1 201 Created
Content-Type: application/json

{
   "id": "9001bcd9-e36a-4f51-bfc6-140c3ad7f9f7",
   "documentName": "TestFile.pdf",
   "contentType": "application/pdf", 
   "size": 4533322
}

注意: 文档上传完成后,上传会话将会删除。

获取上传会话

若要获取上传会话,请将 GET 请求发送到上传 URL。

请求

GET https://print.print.microsoft.com/uploadSessions/5400be13-5a4e-4c20-be70-90c85bfe5d6e?tempauthtoken={token}

响应

HTTP/1.1 200 OK
Content-Type: application/json

{
  "expirationDateTime": "2020-10-25T02:19:38.1694207Z",
  "nextExpectedRanges": [
  "72797-72897",
  "78929-4533322"
  ]
}

代码示例:创建上传会话和上传文档


            GraphServiceClient graphClient = new GraphServiceClient( authProvider );

            var properties = new PrintDocumentUploadProperties
            {
	            DocumentName = "TestFile.pdf",
	            ContentType = "application/pdf",
	            Size = 4533322
            };

            var uploadSession = await graphClient.Print.Printers["{printer-id}"].Jobs["{printJob-id}"].Documents["{printDocument-id}"]
            	.CreateUploadSession(properties)
	            .Request()
	            .PostAsync()

            // if using Graph SDK, maxSliceSize should in multiples of 320 KiB
            int maxSliceSize = 320 * 1024;
            var fileUploadTask =
                new LargeFileUploadTask<PrintDocument>(uploadSession, fileStream, maxSliceSize);

            // Create a callback that is invoked after each slice is uploaded
            IProgress<long> progress = new Progress<long>(prog =>
            {
                Console.WriteLine($"Uploaded {prog} bytes of {fileStream.Length} bytes");
            });

            // Upload the file

            var uploadResult = await fileUploadTask.UploadAsync(progress);

取消上传会话

若要取消上载会话,请向上载 UR L 发送 DELETE 请求。 这应该用于中止上传的方案;例如,如果用户取消传输。

expirationDateTime 通过后,系统将自动清理临时文件及其随附的上载会话。

请求

DELETE https://print.print.microsoft.com/uploadSessions/5400be13-5a4e-4c20-be70-90c85bfe5d6e?tempauthtoken={token}

响应

HTTP/1.1 204 No Content