C# HttpPost方法中获取POST请求JSON数据 适配Node.js后端迁移场景
C# 读取HttpPost请求正文并调用外部API实现方案
1. 定义接收请求的模型类
前端提交的是结构化JSON用户数据,ASP.NET Core会自动反序列化请求正文到匹配的C#类,无需手动读取流解析:
// 和前端User类字段一一对应 public class User { public int? user { get; set; } public string login { get; set; } public string password { get; set; } public string email { get; set; } public string external_user_id { get; set; } public string facebook_id { get; set; } public string twitter_id { get; set; } public string full_name { get; set; } public string phone { get; set; } public string website { get; set; } public string custom_data { get; set; } public string user_tags { get; set; } public string avatar { get; set; } public DateTime? created_at { get; set; } public DateTime? updated_at { get; set; } public DateTime? last_request_at { get; set; } }
2. 控制器中读取POST正文
直接通过[FromBody]特性绑定模型即可获取请求正文内容:
using Microsoft.AspNetCore.Mvc; using System.Net.Http.Headers; using System.Text.Json; [ApiController] [Route("auth")] public class AuthController : ControllerBase { private readonly IHttpClientFactory _httpClientFactory; // 注入HttpClient工厂,用于调用外部API public AuthController(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } [HttpPost("signup")] public async Task<IActionResult> SignUp([FromBody] User reqUser) { try { // 这里可以直接访问reqUser的所有属性,对应请求正文的内容 Console.WriteLine(reqUser.password); // 读取请求头中的cb-token if (Request.Headers.TryGetValue("cb-token", out var cbToken)) { Console.WriteLine(cbToken); } // 构造调用外部API的请求参数,对应原Node.js的userObj var externalReq = new { user = new { login = reqUser.login, password = reqUser.password, email = reqUser.email, full_name = reqUser.full_name, phone = reqUser.phone, website = reqUser.website } }; // 替换为你实际的session_token生成逻辑 var sessionToken = "生成的session_token值"; Console.WriteLine($"token in auth route {sessionToken}"); // 调用外部ConnectyCube API var client = _httpClientFactory.CreateClient(); var requestMsg = new HttpRequestMessage(HttpMethod.Post, "https://api.connectycube.com/users"); requestMsg.Headers.Add("CB-Token", sessionToken); requestMsg.Content = new StringContent(JsonSerializer.Serialize(externalReq), MediaTypeHeaderValue.Parse("application/json")); var response = await client.SendAsync(requestMsg); if (!response.IsSuccessStatusCode) { throw new Exception($"Error message: {response.ReasonPhrase}"); } // 解析外部API返回结果 var externalRes = await response.Content.ReadFromJsonAsync<JsonElement>(); // 合并session_token到返回结果 var resObj = new Dictionary<string, object>(externalRes.Deserialize<Dictionary<string, object>>()) { ["session_token"] = sessionToken }; return Ok(resObj); } catch (Exception ex) { Console.WriteLine(ex); return BadRequest(ex.Message); } } }
3. 服务注册配置
在Program.cs中添加必要的服务注册:
var builder = WebApplication.CreateBuilder(args); // 添加控制器服务 builder.Services.AddControllers(); // 注册HttpClient工厂,避免手动实例化HttpClient的资源泄漏问题 builder.Services.AddHttpClient(); var app = builder.Build(); // 路由配置 app.MapControllers(); app.Run();
特殊场景:手动读取原始请求正文
如果需要获取未反序列化的原始正文字符串,可以用以下方法:
[HttpPost("raw")] public async Task<IActionResult> ReadRawBody() { // 允许重复读取请求流 Request.EnableBuffering(); using var reader = new StreamReader(Request.Body, leaveOpen: true); var rawBody = await reader.ReadToEndAsync(); // 读完重置流位置,方便后续中间件读取 Request.Body.Position = 0; // 后续可手动反序列化rawBody为需要的对象 return Ok(rawBody); }
内容的提问来源于stack exchange,提问作者championq45
相关产品推荐
相关产品推荐

