- 服务器端:当你的 .NET 应用(如 ASP.NET Core MVC / Razor Pages / Minimal API)作为一个 Web 服务器,接收并处理来自客户端的 HTTP 请求时,如何获取所有参数。
- 客户端:当你的 .NET 应用作为一个 HTTP 客户端,向其他 Web 服务器发送 HTTP 请求时,如何设置所有参数。
下面我们分别对这两个场景进行详细说明。

服务器端 - 接收请求参数
当你的应用是服务器时,参数的来源多种多样,ASP.NET Core 通过一个强大的模型绑定系统,将这些来源的参数自动映射到你的 Action 方法的参数中。
以下是参数来源的优先级和详细分类:
路径参数
这是 URL 路径中定义的变量,通常用于标识资源。
- 定义:在路由模板中使用大括号 定义,
api/products/{id}。 - 获取方式:直接在 Action 方法的参数列表中定义一个与路径变量名匹配的参数。
- 示例:
// 路由: /api/products/123 [HttpGet("api/products/{id}")] public IActionResult GetProduct(int id) { // id 的值会被自动绑定成 123 return Ok($"Product ID: {id}"); }
查询字符串
URL 中 之后以 key=value 形式传递的参数。

-
定义:
https://example.com/search?query=asp.net&page=1 -
获取方式:
- 简单类型:直接定义与查询键名匹配的参数。
- 复杂类型:ASP.NET Core 可以自动将查询字符串绑定到复杂对象的属性上。
-
示例:
// URL: /search?query=asp.net&page=1&isActive=true [HttpGet("search")] public IActionResult Search(string query, int page, bool isActive) { // query = "asp.net", page = 1, isActive = true return Ok($"Searching for '{query}', page {page}, active: {isActive}"); } // 绑定到复杂对象 public class SearchOptions { public string Query { get; set; } public int Page { get; set; } public bool IsActive { get; set; } } [HttpGet("search-complex")] public IActionResult SearchComplex([FromQuery] SearchOptions options) { // options 对象会被自动填充 return Ok(options); }
请求正文
通常用于 POST, PUT, PATCH 等方法,数据包含在请求的主体中,格式可以是 JSON, XML, Form Data 等。

-
定义:数据在 HTTP 请求的 body 部分。
-
获取方式:通过
[FromBody]特性标记参数。 -
示例:
public class UserCreateModel { public string Name { get; set; } public string Email { get; set; } } [HttpPost("users")] public IActionResult CreateUser([FromBody] UserCreateModel user) { // user 对象会从请求的 JSON body 中反序列化而来 // 需要 Program.cs 中添加 services.AddControllers() 并配置 JSON 选项 return CreatedAtAction(nameof(GetUser), new { id = 1 }, user); }
表单数据类似,但通常用于 application/x-www-form-urlencoded 或 multipart/form-data 格式。
-
定义:数据以表单形式提交。
-
获取方式:
- 对于
application/x-www-form-urlencoded,使用[FromForm]特性。 - 对于
multipart/form-data(常用于文件上传),也使用[FromForm],并配合IFormFile或IFormFileCollection。
- 对于
-
示例:
// 普通表单 [HttpPost("login")] public IActionResult Login([FromForm] string username, [FromForm] string password) { // ... } // 文件上传 [HttpPost("upload")] public IActionResult UploadFile([FromForm] IFormFile file) { if (file.Length > 0) { // 处理文件... } return Ok(); }
请求头
HTTP 请求头中包含的元信息。
- 定义:如
Authorization,Content-Type,Accept,Custom-Header等。 - 获取方式:使用
[FromHeader]特性。 - 示例:
[HttpGet("api/data")] public IActionResult GetData([FromHeader(Name = "Authorization")] string authToken) { // authToken 会从 "Authorization" 请求头中获取 return Ok($"Auth Token: {authToken}"); }
路由数据
这些是路由系统在匹配 URL 时提取的数据,与路径参数非常相似,但通常在更复杂的路由场景(如约束)或直接通过 RouteData 对象访问时使用。
- 获取方式:通过
HttpContext或RouteData访问。 - 示例:
[HttpGet("api/orders/{orderId}/items/{itemId}")] public IActionResult GetOrderItem() { var orderId = RouteData.Values["orderId"]; var itemId = RouteData.Values["itemId"]; return Ok($"Order: {orderId}, Item: {itemId}"); }
服务和上下文
这些不是传统意义上的“参数”,但它们是处理请求时不可或缺的上下文信息。
-
获取方式:通过依赖注入直接在 Action 方法中声明。
-
常用对象:
HttpContext: 整个 HTTP 请求的上下文,包含所有请求信息(Request, Response, User, Items, RequestServices 等)。HttpRequest: 当前 HTTP 请求对象,可以获取所有原始信息。HttpResponse: 当前 HTTP 响应对象。CancellationToken: 用于取消长时间运行的请求操作。ClaimsPrincipal(User): 当前已认证用户的信息。IConfiguration: 应用配置。- 自定义服务。
-
示例:
[HttpGet("context")] public IActionResult GetContextInfo( HttpContext httpContext, ILogger<HomeController> logger, IConfiguration config) { var userAgent = httpContext.Request.Headers["User-Agent"]; var requestId = httpContext.TraceIdentifier; var appVersion = config["AppSettings:Version"]; logger.LogInformation("Request received."); return Ok($"User Agent: {userAgent}, Request ID: {requestId}, App Version: {appVersion}"); }
客户端 - 发送请求参数
当你的应用是客户端时,通常使用 HttpClient 来发送请求,参数主要通过 HttpRequestMessage 或 HttpClient 的扩展方法(如 GetAsync, PostAsync)来设置。
URL 和查询字符串
这是最常见的 GET 请求参数。
-
设置方式:直接在请求的 URL 中构建查询字符串。
-
示例:
using var client = new HttpClient(); var baseUrl = "https://api.example.com/search"; var query = "asp.net core"; var page = 1; // 方法1: 手动拼接 (不推荐,容易出错) var url1 = $"{baseUrl}?query={query}&page={page}"; // 注意:需要对 query 进行 URL 编码! var encodedQuery = Uri.EscapeDataString(query); var url = $"{baseUrl}?query={encodedQuery}&page={page}"; // 方法2: 使用 UriBuilder (推荐) var builder = new UriBuilder(baseUrl); var query = System.Web.HttpUtility.ParseQueryString(builder.Query); // 需要 System.Web query["query"] = "asp.net core"; query["page"] = "1"; builder.Query = query.ToString(); var finalUrl = builder.ToString(); var response = await client.GetAsync(finalUrl);
请求正文
这是 POST, PUT 等请求的主要参数。
-
设置方式:创建
HttpContent对象(如StringContent,JsonContent,FormUrlEncodedContent)并赋值给HttpRequestMessage.Content。 -
示例:
using var client = new HttpClient(); // JSON 内容 (推荐使用 System.Text.Json) var user = new { name = "John Doe", email = "john.doe@example.com" }; var jsonPayload = System.Text.Json.JsonSerializer.Serialize(user); var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json"); var response = await client.PostAsync("https://api.example.com/users", content); // 表单编码内容 var formData = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("username", "johndoe"), new KeyValuePair<string, string>("password", "123456") }; var formContent = new FormUrlEncodedContent(formData); var response = await client.PostAsync("https://api.example.com/login", formContent);
请求头
用于传递元信息,如认证、内容类型等。
-
设置方式:通过
HttpRequestMessage.Headers或HttpRequestMessage.Content.Headers添加。 -
示例:
using var client = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Post, "https://api.example.com/data"); // 添加到请求头 request.Headers.Add("Accept", "application/json"); request.Headers.Add("User-Agent", "MyDotNetApp/1.0"); request.Headers.Add("Authorization", "Bearer your_token_here"); // 添加到内容头 var jsonContent = new StringContent("{\"key\":\"value\"}", Encoding.UTF8, "application/json"); request.Content = jsonContent; // Content-Type 通常由 StringContent 自动设置,也可以手动覆盖 // request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var response = await client.SendAsync(request);
路径参数
在 RESTful API 中,URL 路径中经常包含资源 ID。
- 设置方式:使用字符串插值或
string.Format将参数嵌入到 URL 中。 - 示例:
using var client = new HttpClient(); int userId = 123; string endpoint = $"https://api.example.com/users/{userId}"; var response = await client.GetAsync(endpoint);
HTTP 方法
这决定了请求的“动作”,本身不是参数,但决定了参数如何被发送(通常是 GET 用查询字符串,POST/PUT 用正文)。
-
设置方式:创建
HttpRequestMessage时指定HttpMethod,或使用HttpClient的便捷方法(GetAsync,PostAsync,PutAsync,DeleteAsync等)。 -
示例:
// 使用便捷方法 await client.GetAsync("..."); // GET await client.PostAsync("...", content); // POST await client.PutAsync("...", content); // PUT await client.DeleteAsync("..."); // DELETE // 使用 HttpRequestMessage (更灵活) var request = new HttpRequestMessage(HttpMethod.Patch, "..."); await client.SendAsync(request);
| 场景 | 参数来源 | 获取/设置方式 | 关键特性/对象 |
|---|---|---|---|
| 服务器端 | 路径参数 | Action 方法参数,与路由模板匹配 | [HttpGet(".../{id}")], int id |
| 查询字符串 | Action 方法参数,[FromQuery],或绑定到复杂对象 |
?key=value, [FromQuery] |
|
| 请求正文 | Action 方法参数,[FromBody] |
POST, PUT, JSON, XML, [FromBody] |
|
| 表单数据 | Action 方法参数,[FromForm] |
application/x-www-form-urlencoded, multipart/form-data |
|
| 请求头 | Action 方法参数,[FromHeader] |
Authorization, Content-Type, [FromHeader] |
|
| 上下文信息 | 依赖注入,通过 HttpContext 访问 |
HttpContext, HttpRequest, HttpResponse, ILogger<T> |
|
| 客户端 | URL/查询字符串 | 构建请求 URL,使用 UriBuilder 或手动拼接(需编码) |
client.GetAsync(url) |
| 请求正文 | 创建 HttpContent 对象 (StringContent, JsonContent 等) |
request.Content = ... |
|
| 请求头 | HttpRequestMessage.Headers.Add() |
request.Headers.Add("Authorization", ...) |
|
| 路径参数 | 字符串插值嵌入 URL | client.GetAsync($"/api/users/{id}") |
|
| HTTP 方法 | HttpClient 便捷方法或 HttpRequestMessage.HttpMethod |
GetAsync, PostAsync, HttpMethod.Post |
理解这些不同来源和设置方式,是熟练掌握 .NET 中 HTTP 请求处理的关键。
