Autodesk-Forge / forge-api-dotnet-client

Forge .Net SDK: Provides .Net SDK to help you easily integrate Forge REST APIs into the application
https://www.nuget.org/packages/Autodesk.Forge/
Apache License 2.0
93 stars 70 forks source link

Streams not handled properly on ObjectApis.UploadObjectXXX methods #8

Open mmartin78 opened 7 years ago

mmartin78 commented 7 years ago

ObjectApis.UploadObject and ObjectApis.UploadObjectAsync fail for certain types of streams. We are using the following WebApi code (some parts omitted) and it crashes:

MultipartMemoryStreamProvider provider = await Request.Content.ReadAsMultipartAsync<MultipartMemoryStreamProvider>(new MultipartMemoryStreamProvider());

foreach (HttpContent content in provider.Contents)
{
     var stream = await content.ReadAsStreamAsync();
     dynamic uploadedObj = await objects.UploadObjectAsync(fileStoreBucket, item.Id, (int)stream.Length, stream, "application/octet-stream");
}

We have tracked it down to the following code in ObjectsApi.cs which does not seem to be handling streams properly:

 if (body != null && body.GetType() == typeof(byte[])) // http body (model) parameter
            {
                localVarPostBody = body; // byte array
            }
            else if (   body != null
                     && (   body.GetType() == typeof(System.IO.FileStream)
                         || body.GetType() == typeof(System.IO.BinaryReader)
                         || body.GetType() == typeof(System.IO.BufferedStream)
                         || body.GetType() == typeof(System.IO.MemoryStream)
                         || body.GetType() == typeof(System.IO.StreamReader)
                        )
                    )
            {
                localVarPostBody = Configuration.ApiClient.toByteArray(body); // byte array
            }
            else if ( body != null )
            {
                localVarPostBody = Configuration.ApiClient.Serialize(body);
            }

We have created a quick fix in a local build, but it would be nice to be able to use the official NuGet library. The fix is simply replacing the above code with this:

localVarPostBody = Configuration.ApiClient.toByteArray(body); // byte array

We can submit a pull request if needed.

provegard commented 3 years ago

In addition, not all streams support synchronous reads.

System.NotSupportedException: Synchronous reads are not supported.
   at Microsoft.AspNetCore.Components.Forms.BrowserFileStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.BufferedStream.Read(Byte[] array, Int32 offset, Int32 count)
   at Autodesk.Forge.Client.ApiClient.toByteArray(Object obj)
cyrillef commented 1 year ago

@mmartin78 - I am not sure what needs to be changed - is the whole code to be replaced by one line?