AyCode.Core/AyCode.Services/Mvc/AcBinaryOutputFormatter.cs

44 lines
1.6 KiB
C#

using System.IO.Pipelines;
using AyCode.Core.Serializers.Binaries;
using Microsoft.AspNetCore.Mvc.Formatters;
namespace AyCode.Services.Mvc;
/// <summary>
/// ASP.NET Core MVC OutputFormatter for AcBinary wire format. Wraps Response.Body as PipeWriter,
/// serializes via AcBinarySerializer.SerializeChunked (raw mode — pure AcBinary bytes, no per-chunk
/// framing). Auto-detected flush strategy on the underlying StreamPipeWriter (sequential per chunk).
/// </summary>
public class AcBinaryOutputFormatter : OutputFormatter
{
/// <summary>Vendor media type. <c>application/vnd.acbinary</c> by default.</summary>
public const string DefaultMediaType = "application/vnd.acbinary";
private readonly AcBinarySerializerOptions _options;
public AcBinaryOutputFormatter(AcBinarySerializerOptions? options = null)
{
_options = options ?? AcBinarySerializerOptions.Default;
SupportedMediaTypes.Add(DefaultMediaType);
}
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
{
if (context is null) throw new ArgumentNullException(nameof(context));
var ct = context.HttpContext.RequestAborted;
var pipeWriter = PipeWriter.Create(context.HttpContext.Response.Body);
try
{
AcBinarySerializer.SerializeChunked(context.Object, context.ObjectType ?? typeof(object), pipeWriter, _options);
}
finally
{
await pipeWriter.CompleteAsync().ConfigureAwait(false);
ct.ThrowIfCancellationRequested();
}
}
protected override bool CanWriteType(Type? type) => true;
}