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

如何在C# Web API客户端中无[FromBody]向.NET Core API传复杂对象

解决方案:无[FromBody]时C#客户端向.NET Core API发送复杂对象

我之前也碰到过一模一样的问题!核心原因是:ASP.NET Core在没有标记[FromBody]的情况下,会默认从表单编码数据(application/x-www-form-urlencoded)或者路由/查询参数里绑定复杂对象;而jQuery的$.post刚好默认就是用这种格式发送数据,所以能自动匹配,但C#客户端如果直接发JSON就会绑定失败。

下面给你具体的实现步骤:

1. 先确认你的控制器方法(补全你给出的代码)

首先确保你的控制器方法是接收FilterModel作为参数,没有[FromBody]:

[Serializable]
public class FilterModel 
{ 
    public int? PageSize { get; set; } 
    public int Page { get; set; } 
}

[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
    [HttpPost("TEST")]
    public virtual int Test(FilterModel filter)
    {
        // 示例逻辑:返回页码×每页数量(如果PageSize有值)
        return filter.PageSize.HasValue ? filter.Page * filter.PageSize.Value : filter.Page;
    }
}

2. C#客户端用HttpClient发送表单编码数据

你需要把FilterModel转换成键值对形式的表单内容,而不是JSON。这里用FormUrlEncodedContent来实现:

using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;

// 注意:HttpClient建议全局复用,不要每次请求都新建
private static readonly HttpClient _httpClient = new HttpClient
{
    BaseAddress = new Uri("https://your-api-base-url/api/Test/")
};

public async Task<int> SendFilterRequest()
{
    // 构建你的FilterModel对象
    var filter = new FilterModel
    {
        Page = 3,
        PageSize = 15
    };

    // 将对象转换为表单键值对(处理可空类型,避免空值问题)
    var formData = new Dictionary<string, string>
    {
        ["Page"] = filter.Page.ToString(),
        ["PageSize"] = filter.PageSize?.ToString() ?? string.Empty
    };

    // 创建表单编码的请求内容
    var requestContent = new FormUrlEncodedContent(formData);

    // 发送POST请求
    var response = await _httpClient.PostAsync("TEST", requestContent);
    response.EnsureSuccessStatusCode(); // 确保请求没有出错

    // 读取返回的整数结果
    var resultStr = await response.Content.ReadAsStringAsync();
    return int.Parse(resultStr);
}

3. 更通用的对象转表单扩展方法

如果你的复杂对象字段很多,可以写一个扩展方法自动转换,避免手动写键值对:

using System.Reflection;
using System.Net.Http;
using System.Collections.Generic;

public static class ObjectToFormExtensions
{
    public static FormUrlEncodedContent ToFormUrlEncodedContent(this object obj)
    {
        if (obj == null) throw new ArgumentNullException(nameof(obj));

        // 反射获取对象的所有非空属性,转换为键值对
        var properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(prop => prop.GetValue(obj) != null)
            .ToDictionary(
                prop => prop.Name,
                prop => prop.GetValue(obj)?.ToString() ?? string.Empty
            );

        return new FormUrlEncodedContent(properties);
    }
}

使用的时候就非常简洁了:

var requestContent = filter.ToFormUrlEncodedContent();

为什么jQuery能轻松实现?

因为jQuery的$.post方法默认会把JS对象序列化为application/x-www-form-urlencoded格式的键值对,和ASP.NET Core默认的绑定规则完全匹配,所以不需要额外配置就能成功绑定到FilterModel。

内容的提问来源于stack exchange,提问作者Kiradien

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:01:01