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

ASP.NET Core 2:如何让[FromBody]无Content-Type时仍用JSON绑定模型?

解决ASP.NET Core 2中[FromBody]无Content-Type时的JSON绑定问题

这个问题我之前也碰到过,ASP.NET Core默认的JSON格式化器确实只会认Content-Type为application/json(或相关变种)的请求。要让它支持无Content-Type的场景,我们可以通过调整输入格式化器的配置来实现,这里有两种实用方案:

方案一:扩展默认JSON格式化器的支持范围

这是最省心的方法,直接让默认的JsonInputFormatter接受所有媒体类型(包括无Content-Type的请求)。在Startup.cs的ConfigureServices方法里,找到Mvc的配置项修改即可:

using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Net.Http.Headers;

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        // 定位到默认的JSON输入格式化器
        var jsonInputFormatter = options.InputFormatters
            .OfType<JsonInputFormatter>()
            .FirstOrDefault();
        
        if (jsonInputFormatter != null)
        {
            // 添加对所有媒体类型的支持,覆盖无Content-Type的情况
            jsonInputFormatter.SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("*/*"));
        }
    })
    .AddJsonOptions(options =>
    {
        // 按需配置JSON序列化规则,比如驼峰命名:
        // options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    });
}

配置完成后,不管请求有没有设置Content-Type,只要请求体是合法JSON,[FromBody]就能正常绑定模型。不过要注意:这个方案会让JSON格式化器优先处理所有请求,如果你的API同时需要支持form-data等其他格式,可能需要调整格式化器的优先级。

方案二:自定义输入格式化器(更精准控制)

如果你不想让JSON格式化器“包揽”所有请求,只想针对无Content-Type的情况生效,可以自定义一个格式化器,继承自JsonInputFormatter并做针对性判断:

首先创建自定义格式化器类:

using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Buffers;
using Microsoft.Extensions.ObjectPool;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters.Json;

public class JsonWithoutContentTypeFormatter : JsonInputFormatter
{
    public JsonWithoutContentTypeFormatter(
        ILogger<JsonInputFormatter> logger,
        JsonSerializerSettings serializerSettings,
        ArrayPool<char> charPool,
        ObjectPoolProvider objectPoolProvider,
        MvcOptions mvcOptions,
        MvcJsonOptions jsonOptions)
        : base(logger, serializerSettings, charPool, objectPoolProvider, mvcOptions, jsonOptions)
    {
        // 保留默认支持的媒体类型,只额外处理无Content-Type的请求
    }

    public override bool CanRead(InputFormatterContext context)
    {
        // 仅当请求没有Content-Type或值为空时,启用当前格式化器
        var contentType = context.HttpContext.Request.ContentType;
        if (string.IsNullOrEmpty(contentType))
        {
            return base.CanRead(context);
        }
        // 其他情况交给默认格式化器处理
        return false;
    }
}

然后在Startup.cs里注册这个自定义格式化器,并把它放到格式化器列表的最前面,确保优先被检查:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        // 获取自定义格式化器所需的依赖项
        var serviceProvider = services.BuildServiceProvider();
        var logger = serviceProvider.GetRequiredService<ILoggerFactory>()
            .CreateLogger<JsonInputFormatter>();
        var jsonOptions = serviceProvider.GetRequiredService<IOptions<MvcJsonOptions>>().Value;
        var charPool = ArrayPool<char>.Shared;
        var objectPoolProvider = serviceProvider.GetRequiredService<ObjectPoolProvider>();

        // 实例化自定义格式化器
        var customFormatter = new JsonWithoutContentTypeFormatter(
            logger,
            jsonOptions.SerializerSettings,
            charPool,
            objectPoolProvider,
            options,
            jsonOptions);
        
        // 插入到格式化器列表首位,保证优先匹配
        options.InputFormatters.Insert(0, customFormatter);
    })
    .AddJsonOptions(options =>
    {
        // 按需配置序列化规则
    });
}

这个方案更灵活,只会处理无Content-Type的请求,不会干扰其他格式的正常解析。

两种方案都能解决你的问题,你可以根据自己的API场景选择合适的一种。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:55:07