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

推荐订阅源

J
Java Code Geeks
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
WordPress大学
WordPress大学
B
Blog RSS Feed
T
The Blog of Author Tim Ferriss
F
Fortinet All Blogs
aimingoo的专栏
aimingoo的专栏
MongoDB | Blog
MongoDB | Blog
博客园 - Franky
C
Check Point Blog
P
Proofpoint News Feed
H
Help Net Security
月光博客
月光博客
博客园_首页
Stack Overflow Blog
Stack Overflow Blog
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
Recent Announcements
Recent Announcements
人人都是产品经理
人人都是产品经理
U
Unit 42
美团技术团队
I
InfoQ
A
About on SuperTechFans

博客园 - 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]