HttpClient.PostAsJsonAsync调用ASP.NET Core Web API返回400:字符串字段必填
问题:ASP.NET Core Web API 发布后提示必填字段缺失(本地Swagger测试正常)
问题场景
编写了一个ASP.NET Core Web API方法,本地通过Swagger测试时一切正常,但发布到非本地环境后,使用C#的HttpClient.PostAsJsonAsync调用返回400错误,提示workReportComment是必填项。Fiddler抓包显示请求体中明明包含该字段,却依然触发验证错误。
API接口代码
[HttpPost] [Route("AddWorkReportToIssue")] [Authorize(Roles = "webAPI_user")] public BugNetWorkReports AddWorkReportToIssue(int issueId, string workReportComment, DateTime workDate, decimal duration, Guid userId)
客户端调用代码
client = new HttpClient(); client.BaseAddress = new Uri(host); client.DefaultRequestHeaders.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); token = await AuthenticateAsync(client, user); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token); BugNetAddWorkReport wr = new BugNetAddWorkReport(); wr.issueId = 2300; // int wr.workReportComment = "This is a unit test"; // string wr.workDate = new DateTime(2025, 11, 10); // datetime wr.duration = 0.5M; // decimal wr.userId = "5f2ab78f-2b9e-4e8d-8e78-1cedbc4bb49a"; // string // all fields are filled... var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }; var result = await client.PostAsJsonAsync<BugNetAddWorkReport>("api/BugNet/AddWorkReportToIssue", wr, options); Console.WriteLine("Inspect result here");
Fiddler抓包结果
请求数据
POST https://<<url here>>/api/BugNet/AddWorkReportToIssue HTTP/1.1 Host: <<url here>> Accept: application/json Authorization: bearer <<token here>> Transfer-Encoding: chunked Content-Type: application/json; charset=utf-8 {"issueId":2300,"workReportComment":"This is a unit test","workDate":"2025-11-10T00:00:00","duration":0.5,"userId":"5f2ab78f-2b9e-4e8d-8e78-1cedbc4bb49a"}
响应数据
HTTP/1.1 400 Bad Request Transfer-Encoding: chunked Content-Type: application/problem+json; charset=utf-8 Server: Microsoft-IIS/10.0 X-Powered-By: ASP.NET Date: Tue, 11 Nov 2025 14:43:11 GMT { "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1", "title": "One or more validation errors occurred.", "status": 400, "errors": { "workReportComment": [ "The workReportComment field is required." ] }, "traceId": "00-ffb71a47d567e6dbedaef18eea7d7dec-392595b93b4c51e7-00" }
问题原因
你的API接口方法直接将参数定义为方法的独立参数,ASP.NET Core默认会从URL查询字符串或表单数据中绑定这些参数,而非从请求体的JSON中读取。
本地Swagger测试时,Swagger会自动把参数拼接成URL查询参数或表单字段发送,所以接口能正确获取到值;但客户端用PostAsJsonAsync把数据放到了请求体的JSON里,接口无法从请求体中读取这些零散参数,导致所有参数都未被绑定,从而触发必填字段的验证错误。
解决方案
方案1:将参数封装为实体类(推荐)
创建与客户端发送数据结构匹配的实体类,并用[FromBody]标记参数,告诉ASP.NET Core从请求体JSON中绑定数据:
// 定义匹配的实体类 public class WorkReportRequest { public int IssueId { get; set; } public string WorkReportComment { get; set; } public DateTime WorkDate { get; set; } public decimal Duration { get; set; } public Guid UserId { get; set; } } // 修改后的API接口 [HttpPost] [Route("AddWorkReportToIssue")] [Authorize(Roles = "webAPI_user")] public BugNetWorkReports AddWorkReportToIssue([FromBody] WorkReportRequest request) { // 从request对象中获取参数:request.IssueId、request.WorkReportComment等 // 原业务逻辑代码... }
方案2:手动读取请求体JSON(临时应急)
如果不想修改接口参数结构,可以手动读取请求体内容并反序列化:
[HttpPost] [Route("AddWorkReportToIssue")] [Authorize(Roles = "webAPI_user")] public async Task<BugNetWorkReports> AddWorkReportToIssue() { using var reader = new StreamReader(Request.Body); var json = await reader.ReadToEndAsync(); var request = JsonSerializer.Deserialize<BugNetAddWorkReport>(json); // 使用request中的参数执行业务逻辑,需自行处理参数验证、类型转换(如userId转Guid) }
方案3:客户端改用查询/表单参数发送(不推荐)
修改客户端代码,将参数作为查询字符串或表单数据发送,而非JSON请求体:
// 查询字符串方式 var queryParams = new Dictionary<string, string> { ["issueId"] = "2300", ["workReportComment"] = "This is a unit test", ["workDate"] = "2025-11-10", ["duration"] = "0.5", ["userId"] = "5f2ab78f-2b9e-4e8d-8e78-1cedbc4bb49a" }; var content = new FormUrlEncodedContent(queryParams); var result = await client.PostAsync("api/BugNet/AddWorkReportToIssue", content);
内容的提问来源于stack exchange,提问作者erict
相关产品推荐
相关产品推荐

