AspNetCore.Docs.Samples/fundamentals/streaming/SynchronousWithNewtonsoftJson/Middleware/SongLyricsMiddleware.cs

57 lines
2.0 KiB
C#
Raw Normal View History

Import samples from external repository (#86) * Replaced stub.txt with the samples from git@github.com:logiclrd/ASPNetCoreStreamingExample.git. * Reformatted to match .editorconfig. * Added an exclusion for Properties folder in .gitignore, since this is where launchSettings.json lives. Added launchSettings.json files. * Added root menus to AsynchronousWithSystemTextJson and SynchronousWithNewtonsoftJson. Updated launchSettings.json in each project correspondingly. Updated Startup.cs to output instructions for the user, since it appears `dotnet run` doesn't actually start a browser. * Added sample DynamicBinaryStream. * Added RootNamespace properties to AsynchronousWithSystemTextJson.csproj and SynchronousWithNewtonsoftJson.csproj. * Corrected folder structure. Removed LICENSE file imported from external repository. * Added comment explaining why we create a separate JsonTextWriter for each line in SongLyricsMiddleware.cs. * Removed unnecessary .gitignore files. * Apparently, Visual Studio was still doing implicit using statements even though it was turned off in the project file. Now it's not doing them, so this commit adds the using statements that were implicit. * Converted projects to use so-called "minimal hosting" with all initialization inside Program.cs instead of using a Startup class. * Updated Microsoft.AspNetCore.Mvc.NewtonsoftJson reference to the latest 7.0.0 prerelease version. * Delete .gitignore * Enabled implicit usings in all projects. Removed unnecessary using statements. Converted all C# source files to file-scoped namespaces. Corrected cases where namespaces including the solution file name (not committed to the repository) were accidentally used. Enabled Nullable annotation in SynchronousWithNewtonsoftJson.csproj. * Lumped all using statements into single blocks. Co-authored-by: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com>
2022-10-14 03:34:38 +08:00
namespace SynchronousWithNewtonsoftJson.Middleware;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using SynchronousWithNewtonsoftJson.Model;
public class SongLyricsMiddleware
{
RequestDelegate _next;
ILyricsSource _lyricsSource;
JsonSerializer _serializer;
public SongLyricsMiddleware(RequestDelegate next, ILyricsSource lyricsSource, JsonSerializer serializer)
{
_next = next;
_lyricsSource = lyricsSource;
_serializer = serializer;
}
public Task InvokeAsync(HttpContext context)
{
if (!context.Request.Path.StartsWithSegments(new PathString("/middleware/sing")))
return _next(context);
else
return InvokeAsyncImplementation(context);
}
static readonly byte[] JSONArrayStart = new byte[] { (byte)'[' };
static readonly byte[] JSONArraySeparator = new byte[] { (byte)',' };
public async Task InvokeAsyncImplementation(HttpContext context)
{
await context.Response.Body.WriteAsync(JSONArrayStart, context.RequestAborted);
while (true)
{
foreach (string line in _lyricsSource.GetSongLyrics())
{
// Since we are performing our own writes outside of the JsonTextWriter, we need it to be logically
// set up and torn down for each object we output. Simply calling Flush() might work in practice but
// is assuming internal implementation details.
using (var streamWriter = new StreamWriter(context.Response.Body))
using (var jsonWriter = new JsonTextWriter(streamWriter))
_serializer.Serialize(jsonWriter, line);
await context.Response.Body.WriteAsync(JSONArraySeparator, context.RequestAborted);
await context.Response.Body.FlushAsync(context.RequestAborted);
await Task.Delay(200);
}
}
// No JSONArrayEnd needs to be written, because the above loop will never exit.
}
}