【问题标题】:How to specify the stream to upload a file to OneDrive using MS Graph如何指定流以使用 MS Graph 将文件上传到 OneDrive
【发布时间】:2020-12-16 17:55:10
【问题描述】:

我正在使用 Angular 9 使用 MS Graph 将文件上传到 OneDrive。

到目前为止,我上传了一个空文件并上传了一个包含一些虚假内容(数据类型)的文件。我想我没有添加正确的流,

我阅读了“Upload or replace the contents of a DriveItem”和另外一堆文件。它说:请求正文的内容应该是要上传的文件的二进制流。

在同一个文档的示例(更新现有文件)部分中,它说:

const stream = The contents of the file goes here.; 
let res = await client.api('/me/drive/items/{item-id}/content') .put(stream);

这是没用的。

我从一个对象中获取文件,我使用

onChangeFilePicker() {
    this.upload(this.filePicker.nativeElement.files)
}

这给了我一个 File 对象的数组。

然后我尝试了很多不同的方法,最后一个

    private async uploadFile(graphClient: Client, folderItemId: string, file: File) {
      file.arrayBuffer().then((buffer: ArrayBuffer) => {
        let u8Buffer = new Uint8Array(buffer)
        graphClient
          .api(`/me/drive/items/${folderItemId}:/${file.name}:/content`)
          .post(u8Buffer.values())
            .then(response => {
                console.log('ok')
            })
            .catch(error => {
                console.error(error.stack)
            })        
      })
  }

创建一个包含两个字节的文件。

你知道如何解决它吗?

【问题讨论】:

  • 我过去试过这个,它奏效了:string path = "D:\\LessThan4MB.txt";字节[] 数据 = System.IO.File.ReadAllBytes(path); using (Stream stream = new MemoryStream(data)) { var item = await _client.Me.Drive.Items[FolderID] .ItemWithPath("LessThan4MB.txt") .Content .Request() .PutAsync(stream);您可以使用内存流和 PutAsync 请求尝试这种方法,看看它是否适合您的场景。
  • 我会在答案中更新它。以便您可以正确阅读代码sn-p。
  • 我阅读了您的回复,谢谢。它是 C#,所以我在 TypeScript 中使用了等效的想法。但它不起作用。我不断收到内容损坏的文件。
  • @DigitalOnion 嗨。我正在尝试将文件上传到一个驱动器,但无法获取访问令牌。你能帮我看看你是怎么做到的吗?如果你能回答这个问题,我还设置了赏金。

标签: angular microsoft-graph-api onedrive


【解决方案1】:

我找到了解决方案,它是关于编码和图形客户端的。

我跳过了 Graph 客户端,转而使用纯 Graph API 请求。这需要传递 Authentication Token,并且需要将请求的 Body 放在一起。虽然我有类似的结果,但当我将 ArrayBuffer 编码为 UInt8Array 时,这些都得到了修复,如下所示:

获取身份验证令牌:

  let graphScopes = new MSALAuthenticationProviderOptions(["Files.ReadWrite.All"]);    
  let userAgentApplication = new UserAgentApplication( { auth: this.authConfiguration} )
  let authProvider = new ImplicitMSALAuthenticationProvider(userAgentApplication, graphScopes );
  
  await authProvider.getAccessToken().
  .then(
    token => {
        let headers = new HttpHeaders({
          'Content-Type':'application/json; charset=utf-8',
          'Authorization': `Bearer ${token}`
        })

然后转换 Array Buffer(建议在:Angular 5 HttpClient post raw binary data

      file.arrayBuffer().then( buffer => {            
          let body = new Uint8Array(buffer)
          let uIntBody = body.buffer;
          

最后发出 HttpClient PUT 请求:

async experimentHTTPPostFile(parentId: string, file: File) {    
  let graphScopes = new MSALAuthenticationProviderOptions(["Files.ReadWrite.All"]);    
  let userAgentApplication = new UserAgentApplication( { auth: this.authConfiguration} )
  let authProvider = new ImplicitMSALAuthenticationProvider(userAgentApplication, graphScopes );
  
  await authProvider.getAccessToken()
  .then(
    token => {
        let headers = new HttpHeaders({
          'Content-Type':'application/json; charset=utf-8',
          'Authorization': `Bearer ${token}`
        })

        file.arrayBuffer().then( buffer => {            
          let body = new Uint8Array(buffer)
          let uIntBody = body.buffer;
        
          let url = `${this.MS_GRAPH_BASE_URL}/me/drive/items/${parentId}:/${file.name}:/content`
          this.http.put(url, uIntBody, { headers: headers }).toPromise()
          .then(response => {
            console.log(response)
          })
          .catch(error => {
            console.error(error)
          });                
        })            
      }
  ).catch(error => {
      console.error(error)
  })
}

效果很好,我用 PDF、JPEG 和其他二进制文件进行了测试。

我尝试使用图形客户端 graphClient.api(...).put(...) 对缓冲区进行相同的 UInt8 转换,但它没有解决问题。

【讨论】:

  • 很高兴听到上述解决方案帮助您前进。
  • 是的,谢谢。似乎该主题没有良好或完整的文档,并且文章正在缓慢推出。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多