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

如何让ASP.NET Core Web API接受所有Content-Type请求?

解决方案:同时支持form-urlencoded和JSON请求体

针对你的场景,最直接且稳定的方案是拆分端点处理不同的Content-Type,同时共享核心业务逻辑,避免自定义格式化器的复杂度。

1. 拆分端点,分别处理两种请求格式

保留[ApiController]特性(它能提供自动模型验证、路由约定等便利),创建两个重载方法,分别指定支持的Content-Type:

[ApiController]
[Route("api/v1/object")]
public class ObjectController : ControllerBase
{
    // 处理application/x-www-form-urlencoded格式的请求
    [HttpPost]
    [Consumes("application/x-www-form-urlencoded")]
    public ObjectInfo CreateObjectFromForm([FromForm] ObjectData objectData)
    {
        return ProcessObjectCreation(objectData);
    }

    // 处理application/json或application/xml格式的请求
    [HttpPost]
    [Consumes("application/json", "application/xml")]
    public ObjectInfo CreateObjectFromBody([FromBody] ObjectData objectData)
    {
        return ProcessObjectCreation(objectData);
    }

    // 核心业务逻辑,抽成内部方法复用
    private ObjectInfo ProcessObjectCreation(ObjectData objectData)
    {
        // 这里写你的创建对象逻辑,比如数据持久化、返回结果等
        return new ObjectInfo { /* 赋值逻辑 */ };
    }
}

方案优势

  • [Consumes]特性会让ASP.NET Core根据请求的Content-Type头自动路由到对应方法
  • [FromForm]专门处理表单编码数据,[FromBody]处理JSON/XML格式,两者互不干扰
  • 核心逻辑复用,避免代码冗余,维护成本更低

2. 为什么去掉[ApiController]后JSON请求报错?

移除[ApiController]时,ASP.NET Core的默认模型绑定规则会改变:

  • 普通控制器的参数默认从表单、路由、查询字符串绑定,不会自动读取请求体中的JSON
  • 此时若要处理JSON请求,必须给参数加上[FromBody]特性,但加了之后,ASP.NET Core会强制要求请求体是JSON/XML格式,导致form-urlencoded请求触发415错误
  • 因此拆分端点是更清晰的解决方式,无需放弃[ApiController]的便利特性

3. 无需回退到System.Net.Http

.NET 7使用Microsoft.AspNetCore.Mvc是完全正确的选择,回退到.NET Framework的System.Net.Http会引入不必要的兼容性问题,也无法利用ASP.NET Core的新特性。

备选方案:自定义输入格式化器(适合不愿拆分端点的场景)

如果你希望用同一个方法处理两种格式,可以自定义输入格式化器,让[FromBody]同时支持form-urlencoded:

步骤1:创建自定义输入格式化器

public class FormUrlEncodedToObjectInputFormatter : TextInputFormatter
{
    public FormUrlEncodedToObjectInputFormatter()
    {
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded"));
        SupportedEncodings.Add(Encoding.UTF8);
        SupportedEncodings.Add(Encoding.Unicode);
    }

    protected override bool CanReadType(Type type)
    {
        // 支持ObjectData类型,也可扩展为支持所有普通类
        return typeof(ObjectData).IsAssignableFrom(type);
    }

    public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
    {
        var request = context.HttpContext.Request;
        using var reader = new StreamReader(request.Body, encoding);
        var formContent = await reader.ReadToEndAsync();
        
        // 解析form-urlencoded为键值对
        var formData = formContent.Split('&')
            .Select(kv => kv.Split('='))
            .ToDictionary(
                kv => Uri.UnescapeDataString(kv[0]), 
                kv => kv.Length > 1 ? Uri.UnescapeDataString(kv[1]) : string.Empty
            );

        // 将键值对映射到ObjectData实例
        var objectData = new ObjectData();
        foreach (var prop in typeof(ObjectData).GetProperties())
        {
            if (formData.TryGetValue(prop.Name, out var value) && !string.IsNullOrEmpty(value))
            {
                try
                {
                    prop.SetValue(objectData, Convert.ChangeType(value, prop.PropertyType));
                }
                catch { /* 处理类型转换失败,比如记录日志 */ }
            }
        }

        return await InputFormatterResult.SuccessAsync(objectData);
    }
}

步骤2:注册格式化器到MVC配置

在Program.cs中添加:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    // 将自定义格式化器插入到输入格式化器列表最前面,优先使用
    options.InputFormatters.Insert(0, new FormUrlEncodedToObjectInputFormatter());
});

var app = builder.Build();

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

步骤3:修改原端点

保留[ApiController]和[FromBody],此时该方法就能同时处理JSON和form-urlencoded请求:

[ApiController]
[Route("api/v1/object")]
[HttpPost]
public ObjectInfo CreateObject([FromBody] ObjectData objectData)
{
    // 业务逻辑
    return new ObjectInfo();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 23:07:04