Search code examples
c#.netiformfile

Converting IFormFile to byte[] - Cannot access a disposed object


I am trying to convert an IFormFile object to a byte[] one, but I am bumping into the same error after several approaches: "Cannot access a disposed object. Object name: 'FileBufferingReadStream'."

DocumentController.Analyse() endpoint

public async Task<ActionResult<List<AnalyseResponse>>> Analyse()
{
    logger.LogInformation($"GET /analyse called");

    //1. Getting cached documents
    var cachedFiles = this.documentService.GetUserDocuments(DEFAULT_USER);
    try
    {
        if (!cachedFiles.Any())
        {
            logger.LogError($"No documents cached for current user={DEFAULT_USER}");
            return StatusCode(400, $"No documents cached for current user={DEFAULT_USER}");
        }

        var fileBytes = new byte[cachedFiles[0].File.Length];
        if (cachedFiles[0].File.Length > 0)
        {
            using (var memoryStream = new MemoryStream())
            {
                await cachedFiles[0].File.CopyToAsync(memoryStream);
               // >> Code execution stops when executing CopyToAsync() <<
                fileBytes = memoryStream.ToArray();
            }
        }
(......)

DocumentService.GetUserDocuments(string userIdentifier)

public List<DocumentDto> GetUserDocuments(string userIdentifier)
{
    this.memoryCache.TryGetValue(userIdentifier, out List<DocumentDto>? userDocs);
    return userDocs;
}

Broader context:

  • This code is part of an API and gets executed when a GET endpoint is hit;
  • I've read that HTTP context logging could influence on this, so I temporarily deactivated NLog just to make sure;

Solution

  • Seems like you storing IFormFile objects in your DocumentService and trying to access them afterwards. IFormFile object lifetime is bound to request it originated from, so when request ends it got disposed. You should not cache them directly, instead you need to store it's content in some storage (of your choice: file, DB, RAM) and keep reference (i.e. file path) to it in DocumentService.