using MessagePack;
using Microsoft.AspNetCore.Mvc.Formatters;
namespace Dpz.Core.WebApi.MessagePackFormatters;
/// <summary>
/// MVC output formatter.
/// </summary>
public class MessagePackOutputFormatter : OutputFormatter
{
readonly MessagePackSerializerOptions _options;
/// <summary>
/// ctor
/// </summary>
/// <param name="options">MessagePack 格式化选项</param>
/// <param name="mediaTypes">支持类型</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="options" /> or <paramref name="mediaTypes" /> is
/// <c>null</c>.
/// </exception>
/// <exception cref="T:System.ArgumentException"><paramref name="mediaTypes" /> collection is empty.</exception>
public MessagePackOutputFormatter(
MessagePackSerializerOptions options,
ICollection<string> mediaTypes
)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
ArgumentNullException.ThrowIfNull(mediaTypes);
if (mediaTypes.Count == 0)
{
throw new ArgumentException("Media type must be specified.", nameof(mediaTypes));
}
foreach (var mediaType in mediaTypes)
{
SupportedMediaTypes.Add(mediaType);
}
}
/// <inheritdoc />
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
{
var writer = context.HttpContext.Response.BodyWriter;
if (context.Object == null)
{
new MessagePackWriter(writer).WriteNil();
}
else
{
var objectType =
context.ObjectType is null || context.ObjectType == typeof(object)
? context.Object.GetType()
: context.ObjectType;
MessagePackSerializer.Serialize(
objectType,
writer,
context.Object,
_options,
context.HttpContext.RequestAborted
);
}
await writer.FlushAsync();
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
这是一个自定义的 MessagePack 输出格式化器,用于在 ASP.NET Core Web API 中支持 MessagePack 序列化格式的响应输出。让我详细解释一下这个代码:
类的作用
MessagePackOutputFormatter 继承自 OutputFormatter,是 ASP.NET Core MVC 框架中用于处理 HTTP 响应输出格式化的组件。它的主要作用是将 C# 对象序列化为 MessagePack 二进制格式并写入 HTTP 响应体。
主要组成部分
1. 字段和构造函数
readonly MessagePackSerializerOptions _options;
- 存储 MessagePack 序列化选项,控制序列化行为
构造函数参数:
options: MessagePack 序列化配置选项mediaTypes: 支持的媒体类型集合(如 "application/x-msgpack")
构造函数中的验证逻辑:
- 检查参数是否为 null
- 确保媒体类型集合不为空
- 将所有支持的媒体类型添加到
SupportedMediaTypes集合中
2. 核心方法 WriteResponseBodyAsync
这是格式化器的核心方法,负责将对象序列化并写入响应体:
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
处理逻辑:
获取响应写入器
var writer = context.HttpContext.Response.BodyWriter;处理 null 对象
if (context.Object == null) { new MessagePackWriter(writer).WriteNil(); }如果要序列化的对象为 null,则写入 MessagePack 的 nil 值
处理非 null 对象
var objectType = context.ObjectType is null || context.ObjectType == typeof(object) ? context.Object.GetType() : context.ObjectType;- 确定要序列化的对象类型
- 如果
context.ObjectType为 null 或者是object类型,则使用实际对象的运行时类型 - 否则使用指定的类型
执行序列化
MessagePackSerializer.Serialize( objectType, writer, context.Object, _options, context.HttpContext.RequestAborted );使用 MessagePack 序列化器将对象序列化到响应体写入器中
刷新缓冲区
await writer.FlushAsync();确保所有数据都被写入到响应流中
使用场景
这个格式化器通常用于:
- 需要高性能二进制序列化的 Web API
- 客户端和服务端都支持 MessagePack 格式的应用
- 需要减少网络传输数据量的场景
集成方式
通常在 Startup.cs 或 Program.cs 中注册:
services.AddMvc(options =>
{
options.OutputFormatters.Add(new MessagePackOutputFormatter(
MessagePackSerializerOptions.Standard,
new[] { "application/x-msgpack" }
));
});
这样,当客户端请求 application/x-msgpack 格式的响应时,框架就会使用这个格式化器来处理输出。
AI 正在分析代码…
评论加载中...