You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 Kestrel中间件如何获取Post/Put请求的入参类类型?

获取.NET 8最小API中POST/PUT请求的入参类型

在.NET 8的Kestrel环境下,要在中间件中获取POST/PUT请求对应的入参类类型,可以通过**端点元数据(Endpoint Metadata)**实现,具体方案如下:

核心思路

最小API的端点配置信息会被封装到RouteHandlerActionDescriptor元数据中,我们可以从HttpContext中拿到当前请求对应的端点,再从中提取带有[FromBody]特性的参数类型。

中间件实现代码

修改你的ValidateModelMiddleware的InvokeAsync方法:

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
    if (context.Request.Method is "POST" or "PUT")
    {
        var endpoint = context.GetEndpoint();
        if (endpoint != null)
        {
            // 获取最小API的路由处理程序描述符
            var actionDescriptor = endpoint.Metadata.GetMetadata<RouteHandlerActionDescriptor>();
            if (actionDescriptor != null)
            {
                // 筛选出带有[FromBody]特性的参数
                var bodyParam = actionDescriptor.Parameters
                    .FirstOrDefault(p => p.ParameterInfo.GetCustomAttributes(typeof(FromBodyAttribute), inherit: true).Any());
                
                if (bodyParam != null)
                {
                    Type requestBodyType = bodyParam.ParameterType;
                    // 此时requestBodyType即为当前请求对应的入参类型(比如MyObject)

                    // 重置请求体流位置,确保可以正常读取
                    context.Request.Body.Position = 0;
                    var requestBodyJson = await new StreamReader(context.Request.Body).ReadToEndAsync();
                    
                    // 反序列化为目标类型
                    var model = JsonSerializer.Deserialize(requestBodyJson, requestBodyType);
                    
                    // 这里添加你的自定义验证逻辑
                }
            }
        }
    }

    await next(context);
}

关键注意事项

  1. 请求体流处理:如果中间件在模型绑定之后执行,请求体流可能已被读取到末尾,需要先重置流位置;或者在中间件管道最前面启用请求体缓冲,避免流无法重复读取:
// 在Program.cs中添加,放在UseMiddleware之前
app.Use(async (context, next) =>
{
    context.Request.EnableBuffering();
    await next();
});
  1. 兼容控制器场景:如果项目同时包含控制器风格的API,只需把RouteHandlerActionDescriptor替换为ControllerActionDescriptor,逻辑通用:
var controllerActionDescriptor = endpoint.Metadata.GetMetadata<ControllerActionDescriptor>();
if (controllerActionDescriptor != null)
{
    var bodyParam = controllerActionDescriptor.Parameters
        .FirstOrDefault(p => p.BindingInfo?.BindingSource == BindingSource.Body);
    // 后续反序列化、验证逻辑与最小API一致
}

内容的提问来源于stack exchange,提问作者ashlar64

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:46:07