如何使用 MS Graph 指定流将文件上传到 OneDrive

How to specify the stream to upload a file to OneDrive using MS Graph

我正在使用 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)
}

这给了我一个文件对象数组。

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

    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)
            })        
      })
  }

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

你知道怎么解决吗?

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

我跳过了 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}`
        })

然后转换数组缓冲区(如建议:

      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 和其他二进制文件进行了测试。

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