Updating Data on a OneNote Page Error, "Timeouts are not supported on this stream"

319 views Asked by At

I have the goal of being able to programmatically update OneNote page data using C#. The Microsoft Graph API reference documentation suggests this can only be done by page element, not by page, and gives the following C# Graph SDK example:

GraphServiceClient graphClient = new GraphServiceClient( authProvider );

var stream = new System.IO.MemoryStream(Encoding.UTF8.GetBytes(@"[
   {
    'target':'#para-id',
    'action':'insert',
    'position':'before',
    'content':'<img src=""image-url-or-part-name"" alt=""image-alt-text"" />'
  }, 
  {
    'target':'#list-id',
    'action':'append',
    'content':'<li>new-page-content</li>'
  }
]
"));

var pages = new OnenotePage();
pages.Content = stream;

await graphClient.Me.Onenote.Pages["{onenotePage-id}"]
    .Request()
    .UpdateAsync(pages);

Below is the relevant snippet of my code:

GraphServiceClient client; // authenticated service client
CancellationToken cancellationToken; // a cancellation token
string userId; // identifier of user whose page contains the paragraph to be updated
string pageId; // identifier of page containing paragraph to be updated
string paragraphId; // identifier of paragraph to be updated
string filePath; // location of text file containing updated paragraph data

await client.Users[userId].Onenote.Pages[pageId]
    .Request()
    .UpdateAsync(new OnenotePage
    {
        Content = new MemoryStream(Encoding.UTF8.GetBytes(
            // [
            //    {
            //       'target':'{paragraphId}',
            //       'action':'replace',
            //       'content':'<p>{File.ReadAllText(filePath)}</p>'
            //    }
            // ] 
            $"[{{'target':'{paragraphId}','action':'replace','content':'<p>{File.ReadAllText(filePath)}</p>'}}]"))
    }, cancellationToken);

Microsoft's REST documentation includes PATCH /users/{id | userPrincipalName}/onenote/pages/{id}/content as a valid HTTP request, so my above code seems like it should work, even though it doesn't use the .Me option as in their example. For some reason, however, my code keeps throwing an InvalidOperationException, declaring that, "Timeouts are not supported on this stream," whenever it tries to execute the await command. Below are the details of the exception:

System.InvalidOperationException
    HResult=0x80131509
    Message=Timeouts are not supported on this stream.
    Source=System.Private.CoreLib
    StackTrace:
     at System.IO.Stream.get_ReadTimeout()

When I try to run the raw REST command on the official Graph Explorer, I get a No Content - 204 message, confirming that the PATCH worked. Please note again, however, that I am instead simply using the C# MS Graph SDK.

Where am I going wrong? How can I accomplish my goal?

EDIT: I still don't have a solution to the SDK throwing InvalidOperationExceptions at me, and thus do not consider this matter resolved, but since the API seems to be working just fine, I went ahead and found a workaround to accomplish my goal. Posted here, in case anyone else encounters my same issue and needs something that works.

GraphServiceClient client; // authenticated service client
CancellationToken cancellationToken; // a cancellation token
string userId; // identifier of user whose page contains the paragraph to be updated
string pageId; // identifier of page containing paragraph to be updated
string paragraphId; // identifier of paragraph to be updated
string filePath; // location of text file containing updated paragraph data

HttpRequestMessage request = new HttpRequestMessage(
    HttpMethod.Patch,
    client.Users[userId].Onenote.Pages[pageId].Content
        .Request()
        .RequestUrl)
{
    Content = new StringContent(
        // [
        //    {
        //       'target':'{paragraphId}',
        //       'action':'replace',
        //       'content':'<p>{File.ReadAllText(filePath)}</p>'
        //    }
        // ]
        $"[{{'target':'{paragraphId}','action':'replace','content':'<p>{File.ReadAllText(filePath)}</p>'}}]",
        Encoding.UTF8,
        "application/json")
};

await client.AuthenticationProvider.AuthenticateRequestAsync(request);
await client.HttpProvider.SendAsync(request);
0

There are 0 answers