title: .NET: How to convert an Azure RetriableStreamImpl into an ASP.Net Core IFormFile?
body: <p>I have files stored in Azure Storage in the form of blobs, one blob per file. Files sizes can go up to ~100MB in size.</p>
  
  <p>I am implementing an API that serves these files to consumers as instance of ASP.Net Core 3.1's <a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.iformfile?view=aspnetcore-3.1" rel="nofollow noreferrer"><code>IFormFile</code></a> interface.</p>
  
  <p>In my server-side implementation of the API I am downloading the files using Azure's <code>BlobClient.DownloadAsync()</code> method. This returns an instance of <a href="https://docs.microsoft.com/en-us/dotnet/api/azure.storage.blobs.models.blobdownloadinfo?view=azure-dotnet" rel="nofollow noreferrer"><code>BlobDownloadInfo</code></a> that contains all the data that I need. Specifically, the file's content are made available through the <code>BlobDownloadInfo.Value.Content</code> property which, at runtime, contains an instance of <code>RetriableStreamImpl</code></p>
  
  <p>I am mapping from the <code>BlobDownaldInfo</code> into an <code>IFormFile</code> using the default implementation, <code>FileInfo</code> class like so:</p>
  
  <pre><code>BlobDownloadInfo response = await blobClient.DownloadAsync();
  
  IFormFile file = new FormFile(
      response.Value.Content, 
      0, // baseStreamOffset
      response.Value.ContentLength, 
      "foo", 
      "bar.txt")
  {
      Headers = new HeaderDictionary(),
      ContentType = response.Value.ContentType,
      ContentDisposition = response.Value.Details.ContentDisposition
  };
  
  </code></pre>
  
  <p>Unfortunately for me, this code throws :</p>
  
  <blockquote>
  <pre><code>System.NotSupportedException : Specified method is not supported.
     at Azure.Core.Pipeline.RetriableStream.RetriableStreamImpl.set_Position(Int64 value)
  </code></pre>
  </blockquote>
  
  <p>It looks to me as though the <code>FormFile</code> constructor is trying to set the stream <code>Position</code> to 0 but that that stream is an <code>RetriableStreamImpl</code> which does not allow setting its <code>Position</code> property.</p>
  
  <p>I've worked around this issue by copying the <code>RetriableStreamImpl</code> contents into a <code>MemoryStream</code> and passing that into the <code>FormFile</code> constructor:</p>
  
  <pre><code>var memoryStream = new MemoryStream();
  response.Value.Content.CopyTo(memoryStream);
  </code></pre>
  
  <p>This works and <strong>my question is</strong> - Is this a good solution? Are there any performance issues I need to address further?</p>