Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get special app folder with the new SDK? #1977

Open
NLLAPPS opened this issue May 2, 2024 · 4 comments
Open

How to get special app folder with the new SDK? #1977

NLLAPPS opened this issue May 2, 2024 · 4 comments
Labels
Needs: Attention 👋 type:question An issue that's a question

Comments

@NLLAPPS
Copy link

NLLAPPS commented May 2, 2024

I am pulling my hair out trying to upload to special app folder https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/drive_get_specialfolder?view=odsp-graph-online

On 5 series, I was simply doing

val specialAppFolder = "approot" val uploadSession = graphServiceClient .me() .drive() .special(specialAppFolder) .itemWithPath(uploadDestination.removePrefix("/")) // removePrefix because OrganiserConverter.fromConfig will return /path/.. .createUploadSession(.....)

On 6+ I cannot figure-out how to get hold of specialAppFolder in order to createUploadSession().

Could someone with a better understanding point me to the right direction please?

@Ndiritu Ndiritu added the type:question An issue that's a question label May 3, 2024
@Ndiritu
Copy link
Contributor

Ndiritu commented May 3, 2024

@NLLAPPS thanks for reaching out.
This should be possible via:

Drive drive = graphServiceClient.me().drive();
DriveItem specialFolder = graphServiceClient.drives().byDriveId(drive.getId()).special().byDriveItemId("{special folder name}").get();
UploadSession uploadSession = graphServiceClient.drives().byDriveId(drive.getId()).items().byDriveItemId(specialFolder.getId()).createUploadSession().post(uploadSessionRequest);

Relevant docs links:
https://learn.microsoft.com/en-us/graph/api/drive-get-specialfolder?view=graph-rest-1.0&tabs=java
https://learn.microsoft.com/en-us/graph/api/driveitem-createuploadsession?view=graph-rest-1.0#create-an-upload-session

@NLLAPPS
Copy link
Author

NLLAPPS commented May 3, 2024

Thank you. I am not usually this thick but getting my head around 6 series proven to be very hard.
This is what I used to to on 5 series

val uploadSession = graphServiceClient
            .me()
            .drive()
            .special("approot")
            .itemWithPath("some/sub/folder/and/filename.txt")
            .createUploadSession(DriveItemCreateUploadSessionParameterSet.newBuilder().withItem(DriveItemUploadableProperties()).build())
            .buildRequest(listOf<Option>(QueryOption("@name.conflictBehavior", "rename")))

Where I was able to upload "filename.txt" to ""some/sub/folder/and/" in "approot" special folder

For 6 series, I am following the guide at https://learn.microsoft.com/en-us/graph/sdks/large-file-upload?tabs=java
Uploading to root with below example works fine.

val myDriveId: String = graphServiceClient.me().drive().get().id
val uploadSession = graphServiceClient.drives()
             .byDriveId(myDriveId)
             .items()
             .byDriveItemId("root:/some/sub/folder/and/filename.txt:")
             .createUploadSession()
             .post(uploadSessionPostRequestBody)

But, I want to upload the file to the special "approot" folder and configure it like this:

val driveId = graphServiceClient.me().drive().get().id
        val specialFolder = graphServiceClient.drives().byDriveId(driveId).special().byDriveItemId("approot").get()
        val driveItem = graphServiceClient.drives()
            .byDriveId(specialFolder.id)
            .items()
            .byDriveItemId("/some/sub/folder/and/filename.txt")
            .createUploadSession()
            .post(uploadSessionPostRequestBody)

Above example fails with
com.microsoft.graph.models.odataerrors.ODataError: Invalid request

Could you tell me how I am supposed to configure DriveItem name and path when uploading to special "approot" folder?

Here is the full log
` --> GET https://graph.microsoft.com/v1.0/users/TokenToReplace/drive
accept: application/json
authorization: Bearer xxxx
--> END GET
<-- 200 https://graph.microsoft.com/v1.0/users/TokenToReplace/drive (433ms)
cache-control: no-store
content-type: application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8
vary: Accept-Encoding
strict-transport-security: max-age=31536000
request-id: xxxxxxxx
client-request-id: xxxxxxxx
odata-version: 4.0
date: Fri, 03 May 2024 09:26:44 GMT
--omitted data---
<-- END HTTP (437ms, 346-byte body)
--> GET https://graph.microsoft.com/v1.0/drives/xxxxxx/special/approot
accept: application/json
authorization: Bearer xxxx
--> END GET
<-- 200 https://graph.microsoft.com/v1.0/drives/xxxxxx/special/approot (137ms)
--omitted data---
<-- END HTTP (145ms, 1059-byte body)
--> POST https://graph.microsoft.com/v1.0/drives/xxxxxx%2111432/items/2024_05_03_09_56_59.mp3/createUploadSession
Content-Length: 55
authorization: Bearer xxxx
accept: application/json
content-type: application/json

 {"item":{"@microsoft.graph.conflictBehavior":"rename"}}
 --> END POST (0-byte body)
 <-- 400      https://graph.microsoft.com/v1.0/drives/xxxxxx%2111432/items/2024_05_03_09_56_59.mp3/createUploadSession (108ms)
 cache-control: no-store
 content-type: application/json
 vary: Accept-Encoding
 strict-transport-security: max-age=31536000
 request-id: 3426f604xxxx
 client-request-id: 3426f604xxxx

 date: Fri, 03 May 2024 09:26:44 GMT

  {"error":{"code":"invalidRequest","message":"Invalid request","innerError":{"date":"2024-05-     03T09:26:44","request-id":"3426f604xxxx","client-request-id":"3426f604xxxx"}}}
  <-- END HTTP (114ms, 218-byte body)`

@NLLAPPS
Copy link
Author

NLLAPPS commented May 3, 2024

I have also dug through traffic of 5 series and noticed that
graphServiceClient .me() .drive() .special("approot").itemWithPath(uploadDestination)

Produces:
https://graph.microsoft.com/v1.0/me/drive/special/approot:/filename.txt:

But
val driveId = graphServiceClient.me().drive().get().id val specialFolder = graphServiceClient.drives().byDriveId(driveId).special().byDriveItemId("approot").get() val driveItem = graphServiceClient.drives() .byDriveId(specialFolder.id) .items() .byDriveItemId(uploadDestination)

Produces below after multple requests:
https://graph.microsoft.com/v1.0/drives/XXXXX%21XXXXX/items/filename.txt/

Isn't there any way to build
https://graph.microsoft.com/v1.0/me/drive/special/approot:/filename.txt:
Saving round trips to the API?

@NLLAPPS
Copy link
Author

NLLAPPS commented May 3, 2024

OK, finally fixed it! See below. I must say it was excruciatingly hard. I hope MS will consider providing upgrade path on significant changes like this in the future. Issue I had created on Feb 17 2024 at Android Samples at https://github.com/microsoftgraph/msgraph-sample-android/issues not even acknowledged yet.

val driveId = graphServiceClient.me().drive().get().id
        val specialFolderId = graphServiceClient.drives().byDriveId(driveId).special().byDriveItemId("approot").get().id
        val driveItemId = "${specialFolderId}:/fileName.txt:"
        val uploadSession = graphServiceClient.drives().byDriveId(driveId)
            .items()
            .byDriveItemId(driveItemId)
            .createUploadSession()
            .post(uploadSessionPostRequestBody)

Above seems to create unnecessary requests. Each get() is a request to API. This was not the case in 5 series. Isn't there a way to construct Special Folder name without request to get IDs? Some sort of hand crafted DriveItemItemRequestBuilder with URL https://graph.microsoft.com/v1.0/me/drive/special/approot:/?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: Attention 👋 type:question An issue that's a question
Projects
None yet
Development

No branches or pull requests

2 participants