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

使用ConsumesAttribute时Request.ContentType为null的问题排查

问题与解决方案:ConsumesAttribute未拦截Content-Type为null的POST请求

问题背景

使用[Consumes]属性限制接口仅处理特定内容类型时,发现该属性不会将Content-Type为null的请求判定为非法。查看ASP.NET Core源码注释可知,无Content-Type的请求不会返回415状态码,这是为了兼容控制器标记[Consumes]同时包含GET动作的场景(GET请求通常无Content-Type)。但标记了[HttpPost]的接口仍收到了Content-Type为null的请求,比如通过以下代码发送的请求:

new HttpClient().PostAsync(url, new ByteArrayContent(new byte[] { 50, 51 }))

修正方案

1. 自定义过滤器实现严格校验

由于默认ConsumesAttribute的设计偏向兼容GET场景,可自定义ActionFilterAttribute,对POST/PUT/PATCH等带请求体的方法强制校验Content-Type:

public class StrictConsumesAttribute : ActionFilterAttribute
{
    private readonly string[] _allowedContentTypes;

    public StrictConsumesAttribute(params string[] allowedContentTypes)
    {
        _allowedContentTypes = allowedContentTypes.Select(ct => ct.ToLowerInvariant()).ToArray();
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var request = context.HttpContext.Request;
        
        // 仅针对带请求体的HTTP方法执行校验
        if (new[] { "POST", "PUT", "PATCH" }.Contains(request.Method))
        {
            var contentType = request.ContentType?.ToLowerInvariant();
            
            // 无Content-Type或不在允许列表中,返回415
            if (string.IsNullOrEmpty(contentType) || !_allowedContentTypes.Contains(contentType))
            {
                context.Result = new StatusCodeResult(StatusCodes.Status415UnsupportedMediaType);
                return;
            }
        }

        base.OnActionExecuting(context);
    }
}

使用示例:

[HttpPost]
[StrictConsumes("application/json", "application/xml")]
public IActionResult SubmitData([FromBody] RequestModel model)
{
    // 业务逻辑
    return Ok();
}

2. 客户端显式设置Content-Type

如果请求由己方客户端发起,可直接为请求内容指定Content-Type:

var content = new ByteArrayContent(new byte[] { 50, 51 });
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); // 替换为你需要的合法类型
await new HttpClient().PostAsync(url, content);

是否属于ASP.NET Core Bug?

这不属于Bug,而是设计权衡的结果:源码注释明确说明该行为是为了支持控制器级[Consumes]搭配GET动作的常见场景。但这种设计确实会导致带请求体的接口无法拦截无Content-Type的请求,你提交的Issue会让官方团队评估是否需要优化逻辑,比如区分GET和带请求体的方法进行差异化校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:32:48