Я работаю с Angular 9, чтобы загрузить файл в OneDrive с помощью MS Graph.
Я дошел до того, что загрузил пустой файл и загрузил файл с некоторым фиктивным содержимым (тип данных). Я полагаю, что добавляю не тот поток,
Я прочитал «Загрузить или заменить содержимое 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.info('ok')
})
.catch(error => {
console.error(error.stack)
})
})
}
который создает файл с двумя байтами.
У вас есть идеи, как это решить?
Я обновлю его в ответе. чтобы вы могли правильно прочитать фрагмент кода.
Прочитал ваш ответ, спасибо. Это C#, поэтому я использовал аналогичные идеи в TypeScript. Но это не работает. Я продолжаю получать файл с поврежденным содержимым.
@DigitalOnion Привет. Я пытаюсь загрузить файлы на один диск и не могу получить токен доступа. Можете ли вы помочь мне с тем, как вы это сделали? Я также назначил награду за вопрос, если вы ответите на него.
Я нашел решение, речь шла о кодировании и клиенте Graph.
Я пропустил Graph Client и пошел на чистые запросы 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}`
})
Затем, чтобы преобразовать буфер массива (как предлагается в: Angular 5 HttpClient публикует необработанные двоичные данные)
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.info(response)
})
.catch(error => {
console.error(error)
});
})
}
).catch(error => {
console.error(error)
})
}
Он работал отлично, я тестировал PDF, JPEG и другие бинарные файлы.
Я попытался выполнить то же преобразование буфера UInt8 с Graph Client graphClient.api(...).put(...), и это не решает проблему.
Рад слышать, что приведенное выше решение помогло вам двигаться вперед.
Да помогло спасибо. Похоже у темы нет хорошей или готовой документации и статьи выкатываются медленно. Еще раз спасибо.
Я пробовал это раньше, и это сработало: string path = "D:\\LessThan4MB.txt"; байт [] данные = System.IO.File.ReadAllBytes (путь); использование (поток потока = новый поток памяти (данные)) { var item = await _client.Me.Drive.Items [ID папки] .ItemWithPath ("LessThan4MB.txt") .Content .Request() .PutAsync<DriveItem> (поток); } Вы можете попробовать этот подход с потоком памяти и запросом PutAsync<DriveItem>, чтобы увидеть, подходит ли он для вашего сценария.