-
Notifications
You must be signed in to change notification settings - Fork 39
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
Unable to use this sdk to upload a file using an upload session to OneDrive #511
Unable to use this sdk to upload a file using an upload session to OneDrive #511
Comments
I did a little more digging. As I understand the next step is to call the Post() method defined in https://github.com/microsoftgraph/msgraph-sdk-go/blob/v1.6.0/drives/item_items_item_create_upload_session_request_builder.go So using the uploadSessionRequestBuilder created in the previous step I tried this below. The second argument has to be of type ItemItemsItemCreateUploadSessionPostRequestBodyable (these names are so long and confusing). ItemItemsItemCreateUploadSessionPostRequestBodyable is an interface type and if I pass a nil as below. I get an error error: error status code received from the APIcode: itemNotFoundmsg: Item not found // ItemItemsItemCreateUploadSessionPostRequestBodyable ItemItemsItemCreateUploadSessionPostRequestBody implements this interface ItemItemsItemCreateUploadSessionPostRequestBodyable so a value of type can be passed as the second argument to the uploadSessionRequestBuilder.Post method above. What should I pass if I am trying to just upload a file "file.txt" sitting in the local project root. Tried this below. requestBody := &drives.ItemItemsItemCreateUploadSessionPostRequestBody{} and instead of nil for the second arg passing requestBody which panics. |
Hi @aakashbanerjee, thanks for trying the Graph SDK. You are currently attemping to create an upload session which would ideally be ready for use when the feature Large file upload is ready. This feature is currently in progress and should be release in the next month. I would not recommend this approach if you are a beginner but If you would like to use the upload session to upload a file before the feature is complete, here is some sample code that you can get started on to use to create an upload session import (
"context"
"fmt"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
abstractions "github.com/microsoft/kiota-abstractions-go"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
"github.com/microsoftgraph/msgraph-sdk-go/drives"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/microsoftgraph/msgraph-sdk-go/models/odataerrors"
"log"
"os"
)
func SampleFileUpload() {
tenantID := "tenantID"
clientID := "clientID"
clientSecret := "clientSecret"
graphcred, err := azidentity.NewClientSecretCredential(
tenantID,
clientID,
clientSecret,
nil,
)
if err != nil {
log.Fatal(err)
}
grclient, err := msgraphsdk.NewGraphServiceClientWithCredentials(graphcred, []string{"https://graph.microsoft.com/.default"})
if err != nil {
log.Fatal(err)
}
// create upload session
driveID := "driveID"
result, err := grclient.Drives().ByDriveId(driveID).Get(context.Background(), nil)
if err != nil {
fmt.Printf("Error getting the drive: %v\n", err)
printOdataError(err)
}
fmt.Printf("Found Drive : %v\n", *result.GetId())
// read file info
data, err := os.ReadFile("path\\to\\file")
if err != nil {
panic(err)
}
// create upload session
driveItemId := "driveItemId"
requestBody := drives.NewItemItemsItemCreateUploadSessionPostRequestBody()
desc := "description"
name := "name"
size := int64(len(data))
uploadProperties := models.NewDriveItemUploadableProperties()
uploadProperties.SetDescription(&desc)
uploadProperties.SetName(&name)
uploadProperties.SetFileSize(&size)
requestBody.SetItem(uploadProperties)
requestBody.SetAdditionalData(map[string]any{"@microsoft.graph.conflictBehavior": "replace"})
uploadSession, err := grclient.Drives().ByDriveId(driveID).Items().ByDriveItemId(driveItemId).CreateUploadSession().Post(context.Background(), requestBody, nil)
if err != nil {
log.Fatal(err)
}
// create an upload request information
requestInfo := abstractions.NewRequestInformation()
requestInfo.UrlTemplate = *uploadSession.GetUploadUrl()
requestInfo.Method = abstractions.PUT
requestInfo.Headers.Add("Content-Type", "application/octet-stream")
requestInfo.Headers.Add("Content-Length", fmt.Sprintf("%d", len(data)))
requestInfo.SetStreamContent(data)
// upload file
errorMapping := abstractions.ErrorMappings{
"4XX": odataerrors.CreateODataErrorFromDiscriminatorValue,
"5XX": odataerrors.CreateODataErrorFromDiscriminatorValue,
}
err = grclient.BaseRequestBuilder.RequestAdapter.SendNoContent(context.Background(), requestInfo, errorMapping)
if err != nil {
log.Fatal(err)
}
}
func printOdataError(err error) {
// excluded for brevity
}
|
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. |
Thanks for that. I ended up using microsoft-authentication-library-for-go/apps/confidential and net/http
To use OneDrive file upload it seems there is a req for a SPO license. As far as I remember I enabled a Microsoft 365 subscription. |
@rkodev I'm afraid I can't get your sample code to work. I'm rather new to MS365 in general, and the msgraph Go sdk in particular, so perhaps I'm missing something obvious. I'm using an app that has the right permissions (as far as I can see), and I'm on a business license. The problem seems to be in creating the upload properties. If I only inlcude the 'name' property, i.e.: ...
requestBody := drives.NewItemItemsItemCreateUploadSessionPostRequestBody()
name := "filename.txt"
uploadProperties := models.NewDriveItemUploadableProperties()
uploadProperties.SetName(&name)
requestBody.SetItem(uploadProperties)
uploadSession, err := client.Drives().ByDriveIdString(<my user id>).Items().ByDriveItemIdString("root").CreateUploadSession().Post(context.Background(), requestBody, nil)
... then the OData error I receive is:
If I add another field to the upload properties, i.e. either 'description' or 'size', the error changes:
I've tried prepending the filename in the upload properties with '/', '/root', '/root:', '/root:/', etc. but that doesn't fix the error. Is there perhaps a different way to construct these upload properties? Edited to add that the method posted by @aakashbanerjee works, so permissions seem to be correct. |
Primary Intent:
Upload a file to OneDrive
What I have tried so far:
Application registration created in Azure AD with required permissions and secret.
Used the App Only Client Credentials flow to create NewClientSecretCredential and graph service client.
I have used these client to Get details of the Drive as below where I want to upload the file.
Following docs here : https://learn.microsoft.com/en-us/graph/api/driveitem-createuploadsession?view=graph-rest-1.0#create-an-upload-session I am trying to create an upload session
//Create an upload session
I am able to get a response and print it.
Where is this struct defined/documented so I can understand what the fields are?
I am unable to understand or move forward with how to use this uploadSessionRequestBuilder to actually upload the file to OneDrive.
Any help is much appreciated. Please advise if I should rather some other recommended sdk to programmatically upload files to OneDrive.
The text was updated successfully, but these errors were encountered: