From 473f51ad591da711bb0eb11b734d6f7c812c7cc9 Mon Sep 17 00:00:00 2001 From: Jeff Putz Date: Thu, 1 Feb 2024 20:34:23 -0500 Subject: [PATCH] PostImage streams from SQL to controller #359 --- .../PostImage/PostImageRepository.cs | 7 ++++++- .../Areas/Forums/Controllers/ImageController.cs | 9 ++++++--- .../Repositories/PostImageRepository.cs | 17 +++++++++++++++++ src/PopForums/Models/PostImage.cs | 10 +++++----- .../Repositories/IPostImageRepository.cs | 2 ++ src/PopForums/Services/PostImageService.cs | 8 ++++++++ 6 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/PopForums.AzureKit/PostImage/PostImageRepository.cs b/src/PopForums.AzureKit/PostImage/PostImageRepository.cs index 35c59c72..db9f2c17 100644 --- a/src/PopForums.AzureKit/PostImage/PostImageRepository.cs +++ b/src/PopForums.AzureKit/PostImage/PostImageRepository.cs @@ -51,7 +51,7 @@ public async Task DeletePostImageData(string id, string tenantID) await container.DeleteBlobAsync(path, DeleteSnapshotsOption.IncludeSnapshots); } - // The next two methods are not used when fetching images from Azure storage. The + // The next three methods are not used when fetching images from Azure storage. The // default SQL implementation does use these. public Task GetWithoutData(string id) @@ -63,4 +63,9 @@ public async Task DeletePostImageData(string id, string tenantID) { throw new NotImplementedException(); } + + public Task GetImageStream(string id) + { + throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/src/PopForums.Mvc/Areas/Forums/Controllers/ImageController.cs b/src/PopForums.Mvc/Areas/Forums/Controllers/ImageController.cs index 5c7a128d..0ca78019 100644 --- a/src/PopForums.Mvc/Areas/Forums/Controllers/ImageController.cs +++ b/src/PopForums.Mvc/Areas/Forums/Controllers/ImageController.cs @@ -72,9 +72,12 @@ public async Task PostImage(string id) return Content(string.Empty); } } - var fullPostImage = await _postImageService.Get(id); - var stream = new MemoryStream(fullPostImage.ImageData); - return File(stream, "image/jpeg"); + + var streamResponse = await _postImageService.GetImageStream(id); + if (streamResponse == null) + return NotFound(); + Response.RegisterForDispose(streamResponse); + return File(streamResponse.Stream, postImageSansData.ContentType); } [HttpPost] diff --git a/src/PopForums.Sql/Repositories/PostImageRepository.cs b/src/PopForums.Sql/Repositories/PostImageRepository.cs index 94b709b7..5f4eb8de 100644 --- a/src/PopForums.Sql/Repositories/PostImageRepository.cs +++ b/src/PopForums.Sql/Repositories/PostImageRepository.cs @@ -44,6 +44,7 @@ await _sqlObjectFactory.GetConnection().UsingAsync(connection => return await image; } + [Obsolete("Use the combination of GetWithoutData(int) and GetImageStream(int) instead.")] public async Task Get(string id) { Task image = null; @@ -51,4 +52,20 @@ await _sqlObjectFactory.GetConnection().UsingAsync(connection => image = connection.QuerySingleOrDefaultAsync("SELECT * FROM pf_PostImage WHERE ID = @id", new {id})); return await image; } + + public async Task GetImageStream(string id) + { + var connection = (SqlConnection)_sqlObjectFactory.GetConnection(); + var command = new SqlCommand("SELECT ImageData FROM pf_PostImage WHERE ID = @id", connection); + command.Parameters.AddWithValue("id", id); + connection.Open(); + var reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess); + if (await reader.ReadAsync() && !await reader.IsDBNullAsync(0)) + { + var stream = reader.GetStream(0); + var streamResponse = new StreamResponse(stream, connection, reader); + return streamResponse; + } + return default; + } } \ No newline at end of file diff --git a/src/PopForums/Models/PostImage.cs b/src/PopForums/Models/PostImage.cs index 2fcd6c35..d57ff06b 100644 --- a/src/PopForums/Models/PostImage.cs +++ b/src/PopForums/Models/PostImage.cs @@ -2,10 +2,10 @@ public class PostImage { - public string ID { get; set; } - public DateTime TimeStamp { get; set; } - public string TenantID { get; set; } - public string ContentType { get; set; } - public byte[] ImageData { get; set; } + public string ID { get; init; } + public DateTime TimeStamp { get; init; } + public string TenantID { get; init; } + public string ContentType { get; init; } + public byte[] ImageData { get; init; } } \ No newline at end of file diff --git a/src/PopForums/Repositories/IPostImageRepository.cs b/src/PopForums/Repositories/IPostImageRepository.cs index 4ecd8886..e2f8ce16 100644 --- a/src/PopForums/Repositories/IPostImageRepository.cs +++ b/src/PopForums/Repositories/IPostImageRepository.cs @@ -4,6 +4,8 @@ public interface IPostImageRepository { Task Persist(byte[] bytes, string contentType); Task GetWithoutData(string id); + [Obsolete("Use the combination of GetWithoutData(int) and GetImageStream(int) instead.")] Task Get(string id); Task DeletePostImageData(string id, string tenantID); + Task GetImageStream(string id); } \ No newline at end of file diff --git a/src/PopForums/Services/PostImageService.cs b/src/PopForums/Services/PostImageService.cs index 487aa5c5..549155c5 100644 --- a/src/PopForums/Services/PostImageService.cs +++ b/src/PopForums/Services/PostImageService.cs @@ -7,7 +7,9 @@ public interface IPostImageService bool ProcessImageIsOk(byte[] bytes, string contentType); Task PersistAndGetPayload(); Task GetWithoutData(string id); + [Obsolete("Use the combination of GetWithoutData(int) and GetImageStream(int) instead.")] Task Get(string id); + Task GetImageStream(string id); Task DeleteTempRecord(string id); Task DeleteTempRecords(string[] ids, string fullText); Task DeleteOldPostImages(); @@ -77,12 +79,18 @@ public async Task GetWithoutData(string id) return postImageSansData; } + [Obsolete("Use the combination of GetWithoutData(int) and GetImageStream(int) instead.")] public async Task Get(string id) { var postImageSansData = await _postImageRepository.Get(id); return postImageSansData; } + public async Task GetImageStream(string id) + { + return await _postImageRepository.GetImageStream(id); + } + public async Task DeleteTempRecord(string id) { var guid = Guid.Parse(id);