React调用.NET Core后端POST接口C#侧接收参数为null如何解决
问题排查与解决方案
核心问题原因
- .NET Core 限制同一个 Action 方法中最多只能使用1次
[FromBody]特性,它会将整个请求体内容绑定到单个参数上,你定义了两个带[FromBody]的字符串参数,框架无法将完整的JSON对象拆分绑定到两个独立参数,因此拿到的都是null。 - 你请求的
Content-Type是application/json,不是表单提交格式,因此HttpContext.Request.Form不存在对应数据,读取自然会报错。 - 你直接读请求体返回空是因为框架在参数绑定时已经读取过一次请求体流,默认请求体流是仅可读一次的,第二次读取时流的位置已经在末尾,所以返回空内容。
- 你之前反序列化逻辑错误:前端提交的是JSON对象结构,不是单纯的JSON字符串,调用
JsonConvert.DeserializeObject<string>(json)必然会抛出异常。
推荐解决方案:定义DTO接收参数
这是.NET Core处理JSON请求的标准写法,可维护性最高:
- 首先定义登录请求的参数模型类:
public class LoginRequest { public string Username { get; set; } public string Password { get; set; } }
- 修改控制器的Login方法:
[HttpPost] public JsonResult Login([FromBody] LoginRequest request) { // 直接通过request对象获取参数即可 System.Diagnostics.Debug.WriteLine("用户名:" + request.Username); System.Diagnostics.Debug.WriteLine("密码:" + request.Password); return new JsonResult("true"); }
备选方案:无需定义DTO,直接接收JSON对象
如果不想单独新建类,可以用Newtonsoft.Json的JObject直接接收:
[HttpPost] public JsonResult Login([FromBody] JObject requestData) { string username = requestData.Value<string>("username"); string password = requestData.Value<string>("password"); // 后续业务逻辑 return new JsonResult("true"); }
如果你需要自行读取请求体的处理方案
如果一定要用StreamReader手动读取请求体,需要先开启请求体重读支持:
[HttpPost] public async Task<JsonResult> Login() { // 开启请求体缓冲,允许多次读取 Request.EnableBuffering(); // 重置流位置到开头 Request.Body.Position = 0; string json = await new StreamReader(Request.Body, Encoding.UTF8).ReadToEndAsync(); // 重置流位置,避免影响后续中间件执行 Request.Body.Position = 0; // 反序列化到对象 LoginRequest request = JsonConvert.DeserializeObject<LoginRequest>(json); string username = request.Username; string password = request.Password; return new JsonResult("true"); }
内容的提问来源于stack exchange,提问作者Bryan Tyrrell
相关产品推荐
相关产品推荐

