如何通过HttpGet向.NET 6.0 Web API传递对象参数实现查询
.NET 6 Web API 查询接口传递含列表对象的正确实现方式
问题背景
开发.NET 6 Web API时,需要传递一个包含字符串列表的对象(后续会新增更多属性)作为查询条件获取数据,原本想用HttpGet实现查询接口,但遇到报错:
TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.
当前定义的模型类:
public class JobRoleDataView { public JobRoleDataView() { } public List<string> Roles { get; set; } }
原API接口代码:
[HttpGet("SearchRecord")] public async Task<IActionResult> SearchRecord(JobRoleDataView JobRoles) { // 业务逻辑代码 return Ok(returnResponse); }
错误原因
HTTP规范明确规定GET/HEAD请求不能携带请求体,你当前的调用方式是把JobRoleDataView放在请求体中传递给GET接口,浏览器的fetch API会直接拦截这种不符合规范的请求,抛出上述错误。
可行解决方案
方案1:改用HttpPost实现查询(简单直接)
虽然REST风格中通常用GET做查询,但如果业务场景允许,直接改用HttpPost是最省事的方式,无需修改前端传参逻辑:
[HttpPost("SearchRecord")] public async Task<IActionResult> SearchRecord([FromBody] JobRoleDataView jobRoles) { // 业务逻辑代码 return Ok(returnResponse); }
注:如果需要让Swagger等文档工具识别这是查询接口,可以添加
[ApiExplorerSettings(GroupName = "查询接口")]做分类标记。
方案2:将模型绑定到查询字符串(符合REST查询规范)
修改API接口,指定从查询字符串绑定模型,前端将对象的属性拆分为多个查询参数传递:
[HttpGet("SearchRecord")] public async Task<IActionResult> SearchRecord([FromQuery] JobRoleDataView jobRoles) { // 业务逻辑代码 return Ok(returnResponse); }
前端调用时,将列表参数重复拼接在URL中,示例URL:
/api/xxx/SearchRecord?Roles=Admin&Roles=Manager&Department=IT
(后续新增的属性直接按&属性名=值的格式追加即可)
方案3:序列化模型为单个查询参数(适合复杂对象)
如果后续模型属性较多,查询字符串会过长,可以将整个对象序列化为JSON字符串,作为单个查询参数传递,后端再反序列化:
后端代码
using System.Text.Json; [HttpGet("SearchRecord")] public async Task<IActionResult> SearchRecord([FromQuery] string filter) { var jobRoles = JsonSerializer.Deserialize<JobRoleDataView>(filter); if (jobRoles == null) { return BadRequest("查询参数格式错误"); } // 业务逻辑代码 return Ok(returnResponse); }
前端处理
将JobRoleDataView对象序列化为JSON字符串,再进行URL编码后传递:
const filter = encodeURIComponent(JSON.stringify({ Roles: ["Admin", "Manager"] })); const url = `/api/xxx/SearchRecord?filter=${filter}`; const response = await fetch(url);
内容的提问来源于stack exchange,提问作者K.Z
相关产品推荐
相关产品推荐

