标记为可选参数的HttpGet为何仍要求传入该参数?
问题解决方案
核心问题分析
- GET请求模型绑定逻辑:ASP.NET Core默认会尝试从请求体绑定复杂对象(如
Employee),但GET请求没有请求体,这直接导致了"A non-empty request body is required."错误。 - 模型验证冲突:如果
Employee类的属性标记了[Required],即使参数声明为Employee?,只要请求中传递了employee的部分字段,模型绑定会自动创建Employee实例并触发必填字段验证,引发"City/Email字段必填"的错误。 - Ajax请求的两处错误:一是
find方法中用了赋值运算符=而非比较运算符===;二是GET请求添加了Content-Type: application/json头,违背了GET请求无请求体的规范。
1. 修正控制器方法
给Employee参数添加[FromQuery]特性,明确从URL查询字符串绑定;同时调整Employee类的必填属性为可空类型(或移除[Required]),避免空实例触发验证。
修改后的控制器代码:
[HttpGet] [Route("/api/getemployee(s)")] public ActionResult GetEditOrView(BaseAction action = BaseAction.GET, [FromQuery] Employee? employee = null) { if (action == BaseAction.EDIT) { employee = employee ?? new Employee(); // 后续业务逻辑 } // ... }
Employee类示例(调整必填属性为可空):
public class Employee { public int? EmployeeId { get; set; } public string? City { get; set; } // 移除[Required]或改为可空类型 public string? Email { get; set; } // 移除[Required]或改为可空类型 // 其他属性 }
2. 修正Ajax请求
移除无效的请求头,修复比较运算符错误,仅在存在有效employee时传递其属性到查询字符串。
修改后的Ajax代码:
function getEditOrView(action, id = null){ let requestData = { action }; if (id !== null) { // 修复比较运算符错误:=改为=== const employee = current_list.find((value) => value.EmployeeId === id); if (employee) { // 将employee属性转为`employee.FieldName=Value`格式的查询参数 Object.entries(employee).forEach(([key, value]) => { requestData[`employee.${key}`] = value; }); } } $.ajax({ type: "GET", url: "/api/getemployee(s)", data: requestData, headers: { 'Accept': 'application/json' // 仅保留Accept头 }, success: function (result) { if (action == @((int)BaseAction.GET)) { current_list = result; BindDataToTable(result); return; } $('body').html(result); }, error: function (jqXHR, textStatus) { // 修正为error(jQuery无fail方法) alert("Request failed: " + textStatus); } }); }
3. Postman测试规范
- 使用GET请求,在Query参数中添加
action(如action=GET或action=EDIT)。 - 若需传递
employee参数,添加形如employee.City=Beijing、employee.Email=test@example.com的查询参数,不要在请求体中传JSON。
内容的提问来源于stack exchange,提问作者Ruturaj Gole
相关产品推荐
相关产品推荐

