You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 01:40:55