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

ASP.NET Core FormData接收对象列表参数为空的解决方法

ASP.NET Core FormData无法接收对象列表问题解决方案

问题根因

ASP.NET Core 默认表单模型绑定不支持直接识别FormData中传入的JSON格式对象集合,其对复杂类型集合的绑定遵循专属的字段命名规则,直接传入JSON数组字符串时,绑定器无法解析结构,最终导致接收到的集合参数为空。


涉及的实体定义

Stavka(商品项)实体

public class Stavka
{
    public string naziv { get; set; }
    public double cenaPoJedinici { get; set; }
    public string jedinicaMere { get; set; }
    public int kolicina { get; set; }

    public Stavka(string naziv, double cenaPoJedinici, string jedinicaMere, int kolicina)
    {
        this.naziv = naziv;
        this.cenaPoJedinici = cenaPoJedinici;
        this.jedinicaMere = jedinicaMere;
        this.kolicina = kolicina;
    }

    public Stavka()
    {
    }
}

Faktura(账单)实体

public class Faktura
{
    public int Id { get; set; }
    public string pibStart { get; set; }
    public string pibEnd { get; set; }
    public DateTime datumGen { get; set; }
    public DateTime datumRok { get; set; }
    public List<Stavka> stavke { get; set;}
    public double cena { get; set; }
    public string tip { get; set; }

    public Faktura(int id, string pibStart, string pibEnd, DateTime datumGen, DateTime datumRok, List<Stavka> stavke, string tip)
    {
        Id = id;
        this.pibStart = pibStart;
        this.pibEnd = pibEnd;
        this.datumGen = datumGen;
        this.datumRok = datumRok;
        this.stavke = stavke;
        this.tip = tip;

        double sumCena = 0;
        // 增加空判断,避免stavke为null时抛出空引用异常
        foreach(Stavka s in stavke ?? new List<Stavka>())
        {
            sumCena += s.kolicina * s.cenaPoJedinici;
        }
        this.cena = sumCena;
    }

    public Faktura()
    {
    }
}

原接口实现(存在绑定问题)

[HttpPost("dodajFakturu")]
public IActionResult dodajFakturu([FromForm]string pibStart, [FromForm]string pibEnd,[FromForm]DateTime datumStart, [FromForm]DateTime datumEnd,[FromForm]List<Stavka> stavkeLis, [FromForm]string tip)
{
    int id = lst.OrderByDescending(p => p.Id).First().Id + 1;
    Faktura f = new Faktura(id, pibStart,pibEnd, datumStart,datumEnd,stavkeLis,tip);
    lst.Add(f);
    return Ok(SveFakture());
}

可行修复方案

方案1:遵循表单绑定规则传参(无需修改接口签名)

ASP.NET Core 表单绑定复杂类型集合时,要求字段名遵循 [参数名].[索引].[属性名] 的平铺格式,索引从0开始连续、不可跳号,不需要传入JSON字符串,直接在FormData中添加对应字段即可。
例如传递2个商品项时,FormData字段如下:

  • stavkeLis[0].naziv = 第一个商品名称
  • stavkeLis[0].cenaPoJedinici = 120.5
  • stavkeLis[0].jedinicaMere = kom
  • stavkeLis[0].kolicina = 2
  • stavkeLis[1].naziv = 第二个商品名称
  • stavkeLis[1].cenaPoJedinici = 45
  • stavkeLis[1].jedinicaMere = kg
  • stavkeLis[1].kolicina = 3

方案2:直接绑定整体实体(推荐)

无需拆分零散参数,直接使用Faktura实体作为FormData绑定对象,模型绑定器会自动匹配所有字段,包括嵌套的商品集合,修改后接口如下:

[HttpPost("dodajFakturu")]
public IActionResult dodajFakturu([FromForm]Faktura model)
{
    int id = lst.OrderByDescending(p => p.Id).First().Id + 1;
    model.Id = id;
    // 重新计算总价
    double sumCena = 0;
    foreach(Stavka s in model.stavke ?? new List<Stavka>())
    {
        sumCena += s.kolicina * s.cenaPoJedinici;
    }
    model.cena = sumCena;

    lst.Add(model);
    return Ok(SveFakture());
}

使用该方案时,Swagger会自动生成所有字段(包括嵌套集合)的表单输入项,无需手动拼接字段名,传参时集合字段按stavke[0].naziv、stavke[0].kolicina的格式填写即可。

方案3:手动反序列化JSON字符串(适配前端固定传JSON的场景)

如果前端逻辑固定要把整个商品集合序列化为JSON字符串作为单个FormData字段传递,需要将集合参数类型改为string,手动执行反序列化,修改后接口如下:

[HttpPost("dodajFakturu")]
public IActionResult dodajFakturu([FromForm]string pibStart, [FromForm]string pibEnd,[FromForm]DateTime datumStart, [FromForm]DateTime datumEnd,[FromForm]string stavkeLis, [FromForm]string tip)
{
    // 手动反序列化JSON字符串为商品集合
    var stavke = JsonSerializer.Deserialize<List<Stavka>>(stavkeLis);
    
    int id = lst.OrderByDescending(p => p.Id).First().Id + 1;
    Faktura f = new Faktura(id, pibStart,pibEnd, datumStart,datumEnd,stavke,tip);
    lst.Add(f);
    return Ok(SveFakture());
}

该方案下传参时,直接把完整的JSON数组字符串作为stavkeLis字段的值传入即可,无需拆分多个表单字段。


问题复现操作演示

Postman操作演示GIF


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 21:33:25