public IActionResult Download([FromRoute] string id) { // Below is a naive implementation which does not fully make use of streaming, resulting // in OutOfMemoryExceptions when retrieving larger payloads. ////var filePath = Path.Combine(_persistenceLocation, $"{id}"); ////var metaFilePath = Path.Combine(_persistenceLocation, $"{id}.meta"); ////if (System.IO.File.Exists(filePath) == false) ////{ //// return NotFound(); ////} ////var result = new FileStreamResult(System.IO.File.OpenRead(filePath), "application/octet-stream"); ////if (System.IO.File.Exists(metaFilePath)) ////{ //// var meta = MetaFileParser.Parse(metaFilePath); //// if (meta != null && !String.IsNullOrWhiteSpace(meta.OriginalFileName)) //// { //// result.FileDownloadName = meta.OriginalFileName; //// } ////} ////return result; // The solution below uses a custom made FileResult implementation which does not buffer the contents // in memory, allowing larger payloads to be transmitted via streaming. // The implementation of the StreamedFileResult class is almost identical to the FileStreamResult class, // except that the StreamedFileResult flushes each time bytes are written to the target-stream. var filePath = Path.Combine(_persistenceLocation, $"{id}"); var metaFilePath = Path.Combine(_persistenceLocation, $"{id}.meta"); if (System.IO.File.Exists(filePath) == false) { return(NotFound()); } string filedownloadName = $"{id}.download"; if (System.IO.File.Exists(metaFilePath)) { var meta = MetaFileParser.Parse(metaFilePath); if (!String.IsNullOrWhiteSpace(meta?.OriginalFileName)) { filedownloadName = meta.OriginalFileName; } } var result = new StreamedFileResult(System.IO.File.OpenRead(filePath), filedownloadName, "application/octet-stream"); return(result); }
public void ReturnsExpectedResult() { const string expectedContent = "message data!"; using (var contentStream = new MemoryStream(Encoding.UTF8.GetBytes(expectedContent))) { var streamedFileResult = new StreamedFileResult(contentStream, "download-filename", "content-type"); StreamedFileResultAssert.OnContent( streamedFileResult: streamedFileResult, assertion: actualContent => Assert.Equal(expectedContent, actualContent)); } }
public async Task DownloadsTheUploadedFileFromController() { // Arrange using (var contentStream = new MemoryStream()) { PayloadController controller = AnonymousPayloadController; await SerializeExpectedContentStream(contentStream, controller); AssignRequestUri(controller.ControllerContext.HttpContext.Request); // Act var actualResult = await controller.Upload() as ObjectResult; // Assert var actualUploadResult = actualResult?.Value as UploadResult; Assert.True(IsDownloadUrlAMatch(actualUploadResult), $"Actual Request Uri doesn't match the expected Uri '{ExpectedRequestUri}'"); StreamedFileResult downloadResult = await DownloadPayload(controller, actualUploadResult); StreamedFileResultAssert.OnContent( downloadResult, actualContent => Assert.Equal(ExpectedContent, actualContent)); } }