Angular 如何使用MS Graph指定将文件上载到OneDrive的流

Angular 如何使用MS Graph指定将文件上载到OneDrive的流,angular,microsoft-graph-api,onedrive,Angular,Microsoft Graph Api,Onedrive,我正在使用Angular 9使用MS Graph将文件上载到OneDrive 我甚至上传了一个空文件,还上传了一个包含一些虚假内容(数据类型)的文件。我想我没有添加正确的流 我读了“”和另一堆文件。它说:请求正文的内容应该是要上传的文件的二进制流。 在同一文档中,在示例(更新现有文件)部分,它说: const stream = The contents of the file goes here.; let res = await client.api('/me/drive/items/{it

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

我甚至上传了一个空文件,还上传了一个包含一些虚假内容(数据类型)的文件。我想我没有添加正确的流

我读了“”和另一堆文件。它说:请求正文的内容应该是要上传的文件的二进制流。

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

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请求。这需要传递身份验证令牌,并需要将请求主体放在一起。虽然我得到了类似的结果,但当我将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}`
        })
然后转换数组缓冲区(如所建议的:)

最后发出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转换,但它并没有解决问题。

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

我跳过了Graph客户端,选择了纯Graph API请求。这需要传递身份验证令牌,并需要将请求主体放在一起。虽然我得到了类似的结果,但当我将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}`
        })
然后转换数组缓冲区(如所建议的:)

最后发出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转换,但没有解决问题。

我过去也尝试过这种方法,效果很好:string path=“D:\\LessThan4MB.txt”;byte[]data=System.IO.File.ReadAllBytes(路径);使用(Stream Stream=new MemoryStream(data)){var item=wait_client.Me.Drive.Items[FolderID].ItemWithPath(“LessThan4MB.txt”).Content.Request().PutAsync(Stream);}您可以使用内存流和PutAsync请求尝试这种方法,看看它是否适合您的场景。我将在答案中更新它。这样您就可以正确地阅读代码片段了。我阅读了您的回复,谢谢。它是C#所以我在TypeScript中使用了相同的思想。但它不起作用。我不断收到一个内容已损坏的文件。@DigitalOnion Hi。我正在尝试将文件上载到一个驱动器,但无法获取访问令牌。你能帮我解释一下你是怎么做到的吗?。如果你能回答我的问题,我也会悬赏。我以前试过这个方法,效果很好:string path=“D:\\LessThan4MB.txt”;byte[]data=System.IO.File.ReadAllBytes(路径);使用(Stream Stream=new MemoryStream(data)){var item=wait_client.Me.Drive.Items[FolderID].ItemWithPath(“LessThan4MB.txt”).Content.Request().PutAsync(Stream);}您可以使用内存流和PutAsync请求尝试这种方法,看看它是否适合您的场景。我将在答案中更新它。这样您就可以正确地阅读代码片段了。我阅读了您的回复,谢谢。它是C#所以我在TypeScript中使用了相同的思想。但它不起作用。我不断收到一个内容已损坏的文件。@DigitalOnion Hi。我正在尝试将文件上载到一个驱动器,但无法获取访问令牌。你能帮我解释一下你是怎么做到的吗?。如果你能回答我的问题,我还悬赏了你。很高兴听到上述解决方案帮助你前进。是的,它帮助了你,谢谢。该主题似乎没有好的或完成的文档,文章的发布速度很慢。再次感谢。很高兴听到上述解决方案帮助您前进。是的,它帮助了您。谢谢。该主题似乎没有好的或完成的文档,文章的发布速度很慢。再次感谢。