From 42c73031bee52859fbe294a607dc56a83fac36df Mon Sep 17 00:00:00 2001 From: Fiyaz Bin Hasan Date: Tue, 12 Jul 2022 23:57:48 +0600 Subject: [PATCH 1/3] sample for Results.Stream --- .../ResultsStreamSample/Program.cs | 43 +++++++++++++++++++ .../ResultsStreamSample.csproj | 19 ++++++++ .../resultsStream/7.0-samples/readme.txt | 1 - 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs create mode 100644 aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj delete mode 100644 aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/readme.txt diff --git a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs new file mode 100644 index 000000000000..873d8bc73c83 --- /dev/null +++ b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs @@ -0,0 +1,43 @@ +using Azure.Storage.Blobs; +using Microsoft.Net.Http.Headers; + +var builder = WebApplication.CreateBuilder(args); + +var app = builder.Build(); + +// For local development use Azure Storage Emulator and Azure Storage Explorer +// https://docs.microsoft.com/en-us/azure/storage/common/storage-use-emulator +// https://azure.microsoft.com/en-us/features/storage-explorer/ +app.MapGet("/stream-image", async () => +{ + BlobContainerClient blobContainerClient = new BlobContainerClient("UseDevelopmentStorage=true", "pictures"); + BlobClient blobClient = blobContainerClient.GetBlobClient("microsoft.jpeg"); + return Results.Stream(await blobClient.OpenReadAsync(), "image/jpeg"); +}); + +app.MapGet("/stream-video", async (HttpContext http) => +{ + BlobContainerClient blobContainerClient = new BlobContainerClient("UseDevelopmentStorage=true", "videos"); + BlobClient blobClient = blobContainerClient.GetBlobClient("earth.mp4"); + + var properties = await blobClient.GetPropertiesAsync(); + + DateTimeOffset lastModified = properties.Value.LastModified; + long length = properties.Value.ContentLength; + + long etagHash = lastModified.ToFileTime() ^ length; + var entityTag = new EntityTagHeaderValue('\"' + Convert.ToString(etagHash, 16) + '\"'); + + http.Response.Headers.CacheControl = "public,max-age=86400"; + + // This is an alias for File(Stream, string, string?, DateTimeOffset?, EntityTagHeaderValue?, bool); + // When fileDownloadName: "rotating-earth.mp4" is added the Content-Disposition header is set to, 'attachment; filename="rotating-earth.mp4"' + // Else it will show the video inline in the browser + return Results.Stream(await blobClient.OpenReadAsync(), + contentType: "video/mp4", + lastModified: lastModified, + entityTag: entityTag, + enableRangeProcessing: true); +}); + +app.Run(); diff --git a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj new file mode 100644 index 000000000000..0a65f7d5c6ee --- /dev/null +++ b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj @@ -0,0 +1,19 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + + + diff --git a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/readme.txt b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/readme.txt deleted file mode 100644 index 655bdceab454..000000000000 --- a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/readme.txt +++ /dev/null @@ -1 +0,0 @@ -Create sample code here then delete this file. \ No newline at end of file From 31feea16c8410784e80ae9f1e92c351b6dabe90e Mon Sep 17 00:00:00 2001 From: Fiyaz Bin Hasan Date: Wed, 13 Jul 2022 00:49:32 +0600 Subject: [PATCH 2/3] sample extended --- .../ResultsStreamSample/Program.cs | 18 ++++++++++++++++++ .../ResultsStreamSample.csproj | 5 ++--- .../wwwroot/img/microsoft.jpeg | Bin 0 -> 36133 bytes 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/wwwroot/img/microsoft.jpeg diff --git a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs index 873d8bc73c83..22053cd68069 100644 --- a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs +++ b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs @@ -1,10 +1,28 @@ using Azure.Storage.Blobs; using Microsoft.Net.Http.Headers; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.Processing; var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); +app.MapGet("/process-image", (HttpContext http, CancellationToken token) => +{ + http.Response.Headers.CacheControl = $"public,max-age={TimeSpan.FromHours(24).TotalSeconds}"; + return Results.Stream(stream => ProcessImage(stream, token), "image/jpeg"); +}); + +async Task ProcessImage(Stream stream, CancellationToken token) +{ + using var image = await Image.LoadAsync("wwwroot/img/microsoft.jpeg", token); + int width = image.Width / 2; + int height = image.Height / 2; + image.Mutate(x => x.Resize(width, height)); + await image.SaveAsync(stream, JpegFormat.Instance, cancellationToken: token); +} + // For local development use Azure Storage Emulator and Azure Storage Explorer // https://docs.microsoft.com/en-us/azure/storage/common/storage-use-emulator // https://azure.microsoft.com/en-us/features/storage-explorer/ diff --git a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj index 0a65f7d5c6ee..439cb362b58d 100644 --- a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj +++ b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj @@ -1,4 +1,4 @@ - + net7.0 @@ -12,8 +12,7 @@ - - + diff --git a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/wwwroot/img/microsoft.jpeg b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/wwwroot/img/microsoft.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..4348947d839eb26a8a1300ea02d54c1fac7b9f10 GIT binary patch literal 36133 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 rd_~|Z0$&mMiojO{z9R4yfv*UBMc^v}UlI6 Date: Wed, 13 Jul 2022 01:34:42 +0600 Subject: [PATCH 3/3] with cancellation token --- .../7.0-samples/ResultsStreamSample/Program.cs | 10 +++++----- .../ResultsStreamSample/ResultsStreamSample.csproj | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs index 22053cd68069..2c6efcf0a1d4 100644 --- a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs +++ b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/Program.cs @@ -26,19 +26,19 @@ async Task ProcessImage(Stream stream, CancellationToken token) // For local development use Azure Storage Emulator and Azure Storage Explorer // https://docs.microsoft.com/en-us/azure/storage/common/storage-use-emulator // https://azure.microsoft.com/en-us/features/storage-explorer/ -app.MapGet("/stream-image", async () => +app.MapGet("/stream-image", async (CancellationToken token) => { BlobContainerClient blobContainerClient = new BlobContainerClient("UseDevelopmentStorage=true", "pictures"); BlobClient blobClient = blobContainerClient.GetBlobClient("microsoft.jpeg"); - return Results.Stream(await blobClient.OpenReadAsync(), "image/jpeg"); + return Results.Stream(await blobClient.OpenReadAsync(cancellationToken: token), "image/jpeg"); }); -app.MapGet("/stream-video", async (HttpContext http) => +app.MapGet("/stream-video", async (HttpContext http, CancellationToken token) => { BlobContainerClient blobContainerClient = new BlobContainerClient("UseDevelopmentStorage=true", "videos"); BlobClient blobClient = blobContainerClient.GetBlobClient("earth.mp4"); - var properties = await blobClient.GetPropertiesAsync(); + var properties = await blobClient.GetPropertiesAsync(cancellationToken: token); DateTimeOffset lastModified = properties.Value.LastModified; long length = properties.Value.ContentLength; @@ -51,7 +51,7 @@ async Task ProcessImage(Stream stream, CancellationToken token) // This is an alias for File(Stream, string, string?, DateTimeOffset?, EntityTagHeaderValue?, bool); // When fileDownloadName: "rotating-earth.mp4" is added the Content-Disposition header is set to, 'attachment; filename="rotating-earth.mp4"' // Else it will show the video inline in the browser - return Results.Stream(await blobClient.OpenReadAsync(), + return Results.Stream(await blobClient.OpenReadAsync(cancellationToken: token), contentType: "video/mp4", lastModified: lastModified, entityTag: entityTag, diff --git a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj index 439cb362b58d..f8194fa82a16 100644 --- a/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj +++ b/aspnetcore/fundamentals/minimal-apis/resultsStream/7.0-samples/ResultsStreamSample/ResultsStreamSample.csproj @@ -15,4 +15,10 @@ + + + PreserveNewest + + +