.NET Graph SDK - OneDrive File Upload Fails with “

2019-07-25 07:41发布

问题:

Trying to upload file using the .NET SDK for Microsoft Graph. Here is the code:

 DriveItem file = new DriveItem()
        {
            File = new Microsoft.Graph.File(),
            Name = filename,
            ParentReference = new ItemReference()
            {
                DriveId = parent.ParentReference.DriveId,
                Path = path + "/" + filename
            }
        };

        var freq = _client
                .Me
                .Drive
                .Items[parent.Id]
                .Children
                .Request();

        // add the drive item
        file = await freq.AddAsync(file);

        DriveItem uploadedFile = null;
        using (MemoryStream stream = new MemoryStream(data))
        {
            var req = _client
                .Me
                .ItemWithPath(path + "/" + file.Name)
                .Content
                .Request();

            stream.Position = 0;
            // upload the content to the driveitem just created
            try
            {
                uploadedFile = await req.PutAsync<DriveItem>(stream);
            }
            catch(Exception ex)
            {
                Debug.WriteLine("File Put Error"); <<< FAILS HERE
            }
        }

        return uploadedFile;

An exception is thrown on the req.PutAsync method to upload the byte array containing the file contents. I am just testing with a simple text file, less than 100 bytes in size. The exception contains Bad Request and Unsupported segment type.

The file is created in OneDrive, but contains 0 bytes.

回答1:

Me.ItemWithPath() requires the full path after /me. For example, _client.Me.ItemWithPath("/drives/driveId/items/itemId:/file/path"). This method is so the Path returned on the ItemReference returned via the API can be passed into the ItemWithPath method without any processing.

What you'll want to use is:

var req = _client
            .Me
            .Drive
            .ItemWithPath(path + "/" + file.Name)
            .Content
            .Request();

or:

var req = _client
            .Me
            .ItemWithPath(file.ParentReference.Path + "/" + file.Name)
            .Content
            .Request();


回答2:

I have found that it is sometimes easier to skip the path in lee of setting the containing folder id in the SDK statement... works in OneDrive and unified groups..

var createdFile = await graphClient.Me.Drive
                         .Items[currentDriveFolder.id]
                         .ItemWithPath(fileName)
                         .Content.Request()
                         .PutAsync<DriveItem>(stream);

I would really like to be able to just set drive id and folder id like this:

var createdFile = await graphClient
                        .Drives[driveId]
                        .Items[folderId]
                        .ItemWithPath(fileName)
                        .Content
                        .Request()
                        .PutAsync<DriveItem>(stream);