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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 20:45:08