惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
N
Netflix TechBlog - Medium
F
Fortinet All Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
宝玉的分享
宝玉的分享
Y
Y Combinator Blog
博客园 - 聂微东
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
B
Blog RSS Feed
小众软件
小众软件
The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI
Microsoft Azure Blog
Microsoft Azure Blog
V
V2EX
B
Blog
H
Help Net Security
D
Docker
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
罗磊的独立博客
月光博客
月光博客
博客园 - 司徒正美

博客园 - Albert_MIN

在 ASP.NET Core 中创建中间件的五种方式 Content-Type 对应不同的前端数据结构与构造方式 Revit二次开发 钢筋生成API(二) Revit二次开发 钢筋生成API(一) revit二次开发 钢筋布置方式 revit二次开发之 钢筋功能详细分析 revit 二次开发之收集器、过滤器和选择器 Revit Server的注意要配置说明 WCF文件配置服务 WCF服务的各种绑定 Revit二次开发之 对象的隐藏与显示 Revit二次开发之 GeometryObject分析 Revit二次开发之 Material 分析 Revit二次开发之 PolymeshTopology Revit 二次开发之 图纸的导出 Revit开发之 IExportContext接口详细 JavaScript 困惑之 ArrayBuffer JS 困惑之this的指向 Revit二次开发之 族的创建 Revit二次开发 钢筋生成 Revit二次开发之 尺寸标线(二) Revit二次开发之 尺寸标线
在 ASP.NET Core MVC 中,接收数据的几种方式
Albert_MIN · 2026-07-04 · via 博客园 - Albert_MIN

在 ASP.NET Core MVC 中,接收数据本质靠「模型绑定(Model Binding)」,根据数据来源和 Content-Type 不同,有多种标准写法。下面按最常见的使用场景系统梳理。


一、按「数据来源」划分的接收方式

1️⃣ 从 URL(Query / Route)接收

✅ Query 参数(?id=1

public IActionResult GetUser(int id)
{
    return Ok(id);
}

或显式声明:

public IActionResult GetUser([FromQuery] int id)

📌 适用于:GET请求


✅ Route 参数(/user/1

[HttpGet("user/{id}")]
public IActionResult GetUser(int id)
{
    return Ok(id);
}

显式写法:

public IActionResult GetUser([FromRoute] int id)

2️⃣ 从请求体(Body)接收

✅ JSON(application/json)→ [FromBody]

👉 前后端分离最常用

public record UserDto(string Name, int Age);

[HttpPost]
public IActionResult CreateUser([FromBody] UserDto user)
{
    return Ok(user);
}

前端示例:

fetch('/api/user', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'tom', age: 18 })
});

⚠️ 注意:

  • 一个 Action 只能有一个 [FromBody]

  • 必须是 application/json


✅ 表单(application/x-www-form-urlencoded

public IActionResult Login([FromForm] string username, [FromForm] string password)

或绑定到模型:

public class LoginVm
{
    public string Username { get; set; }
    public string Password { get; set; }
}

[HttpPost]
public IActionResult Login(LoginVm vm)

📌 前端对应:

const params = new URLSearchParams();
params.append("username", "tom");
params.append("password", "123");

fetch("/login", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: params
});

✅ 文件上传(multipart/form-data

[HttpPost]
public async Task<IActionResult> Upload(IFormFile file)
{
    using var stream = file.OpenReadStream();
    

多个文件:

public async Task<IActionResult> Upload(List<IFormFile> files)

配合 FormData:

const formData = new FormData();
formData.append("file", input.files[0]);

不能[FromBody]


3️⃣ 混合来源(推荐做法)

[HttpPost("user/{id}")]
public IActionResult UpdateUser(
    [FromRoute] int id,
    [FromQuery] string source,
    [FromBody] UserDto user)

二、按「参数绑定特性」速查表

特性

数据来源

常见 Content-Type

默认

Query / Form

-

[FromRoute]

URL 路径

-

[FromQuery]

URL 查询字符串

-

[FromBody]

Request Body

application/json

[FromForm]

Form 表单

application/x-www-form-urlencoded/ multipart/form-data

[FromHeader]

请求头

-

[FromServices]

依赖注入

-


三、模型绑定常见规则

✅ 属性名匹配(不区分大小写)

可绑定到:

public string Name { get; set; }

✅ 复杂对象 + 集合

{
  "name": "Tom",
  "skills": ["C#", "Java"]
}
public record UserDto(string Name, List<string> Skills);

✅ 自定义绑定(高级)

  • IModelBinder

  • [ModelBinder(typeof(...))]


四、常见坑 & 排查点

JSON 用 [FromForm]

→ 永远拿不到值

[FromBody]用两次

→ 运行时异常

文件上传却用 JSON

IFormFile为 null

想接表单又想接 JSON?

→ 不行,一个 Action 只能选一种 Body 绑定方式


五、一句话选型建议

场景

推荐方式

REST API

[FromBody] + JSON

传统 MVC 表单

默认绑定 / [FromForm]

文件上传

IFormFile + multipart

GET 查询

[FromQuery]

RESTful 资源

[FromRoute]