2
votes

I am trying to create a new SharePoint DriveItem using the content of an existing DriveItem using the Microsoft Graph API. However, I am getting the error below when attempting to create the DriveItem. Can somebody explain why?

Edit: Simplified to use manually-created MemoryStream object

GraphServiceClient graphClient = GraphSDKHelper.GetAuthenticatedClient();
using (var docStream = new MemoryStream(1024))
{   
   var doc = new DriveItem
   {
        Content = docStream,
        Name = "00_newDoc.docx",
        ParentReference = new ItemReference
        {
            Id = "<folderId"
        }
    };
    var resultItem = await graphClient.Drives["<driveId>"].Items["<folderId>"].Request().CreateAsync(driveItem);
}

I can upload the file content directly with the following, but I then lose the ability to specify more metadata in the DriveItem in a single call.

var resultItem = await graphClient.Drives["<driveId>"].Items["<folderId>"].ItemWithPath("00_newDoc.docx").content.Request().PutAsync<DriveItem(docStream);

Error:

Error getting value from 'ReadTimeout' on 'System.IO.MemoryStream'.
at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType) at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType) at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer) at Microsoft.Graph.Serializer.SerializeObject(Object serializeableObject) at Microsoft.Graph.BaseRequest.d__36.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Graph.BaseRequest.d__321.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Graph.DriveItemRequest.<CreateAsync>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at Informa.eDocs.AzureFunctions.Functions.PostDocToSharePoint.d__0.MoveNext()

Inner Exception:

Timeouts are not supported on this stream. at System.IO.Stream.get_ReadTimeout() at GetReadTimeout(Object ) at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)

1

1 Answers

0
votes

I don't know what the issue is that you are encountering.

With that said, is there a reason for downloading the file stream only to upload it again as a new driveitem?

Have you considered using the copy functionality? It should work something like this (I haven't tried it yet):

// Copy item reference
ItemReference iRef = new ItemReference()
{
    DriveId = "b!ez3F6Nysf0yYklsI2gUdcx4e7pSsSDZClwfWe3rFh4mSiYpAIn5zRLcsEeS7g5dr",
    Id = "01YYVWN6F6Y2GOVW7725BZO354PWSELRRZ"
};

// Copy it
await graphClient.Me.Drives["<driveId>"].Items["<ItemId>"].Copy("copiedItem.txt", iRef).Request().PostAsync();

Update

The API is not intended to be used this way. I don't know the reason why it can't be done in a single call. I do know that you must first create the item with a POST (example shows a folder, but the idea is the same for a file), and then PUT the content stream in a subsequent call.