如何仅为单个端点配置专属InputFormatter 无需全局注册?
单个端点配置专属InputFormatter的实现方案
以下方案采用ASP.NET Core原生API实现,无过时依赖,仅作用于指定端点,无需全局注册格式化器或全局中间件。
实现原理
InputFormatter的执行优先级远高于ActionFilter,在模型绑定阶段就已完成输入解析,因此运行时在ActionFilter中修改格式化器列表无法生效,老版本相关API已被官方移除。我们可以通过**Mvc约定(Action Convention)**在应用启动的Action元数据构建阶段,仅为指定端点注入专属InputFormatter。
实现步骤
- 第一步:定义专属标记特性
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class UseCustomInputFormatterAttribute : Attribute { }
- 第二步:实现自定义InputFormatter(按你的业务需求实现即可,示例结构如下)
public class MyCustomInputFormatter : InputFormatter { public MyCustomInputFormatter() { // 配置该格式化器支持的媒体类型,例如自定义的application/x-custom SupportedMediaTypes.Add("application/x-custom"); } public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context) { // 你的自定义解析逻辑 var request = context.HttpContext.Request; // ......解析得到请求模型 return await InputFormatterResult.SuccessAsync(/* 解析后的模型 */); } }
- 第三步:注册Mvc约定,仅为标记特性的端点注入格式化器
在Program.cs中添加如下配置:
builder.Services.AddControllers(options => { options.Conventions.Add(new CustomInputFormatterConvention()); }); // 约定类实现 public class CustomInputFormatterConvention : IActionModelConvention { public void Apply(ActionModel action) { if (action.Attributes.OfType<UseCustomInputFormatterAttribute>().Any()) { // 仅给当前匹配的Action添加自定义格式化器 action.InputFormatters.Add(new MyCustomInputFormatter()); } } }
- 第四步:给目标业务端点添加标记特性
[ApiController] [Route("api/business")] public class BusinessController : ControllerBase { [HttpPost("special")] [UseCustomInputFormatter] // 仅该端点会启用自定义InputFormatter public IActionResult SpecialBusinessEndpoint([FromBody] YourBusinessRequest request) { // 你的业务逻辑 return Ok(); } }
补充说明
如果你的自定义InputFormatter仅处理特定的媒体类型,也可以配合[Consumes]特性进一步限制端点的请求类型,避免和默认格式化器的处理范围冲突。
内容的提问来源于stack exchange,提问作者onefootswill
相关产品推荐
相关产品推荐

