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

ViewModel的AllFindedBrands属性无法传递到Controller的SearchBrandResult方法

问题原因及解决方案

核心问题

你尝试通过asp-route-AllFindedBrands传递List<BrandList>类型的复杂对象,但ASP.NET MVC的路由参数仅支持简单类型(字符串、数字等),无法自动序列化/反序列化集合类对象,导致该属性无法正确绑定到POST方法的模型中。同时,你的表单也没有将AllFindedBrands的内容渲染为可被模型识别的表单字段,后台自然无法获取到该值。

解决方案

方案1:用隐藏字段渲染集合内容

在表单内循环生成AllFindedBrands每个元素的隐藏字段,让模型绑定能从POST数据中解析出完整集合:

<form asp-controller="Search" asp-action="SearchBrandResult" method="post">
    <!-- 保留其他路由参数或直接用asp-for绑定 -->
    <input type="hidden" asp-for="Articul" />
    <input type="hidden" asp-for="idClient" />

    <!-- 循环生成AllFindedBrands的隐藏字段 -->
    @for (int i = 0; i < Model.AllFindedBrands.Count; i++)
    {
        <input type="hidden" asp-for="AllFindedBrands[i].Id" />
        <input type="hidden" asp-for="AllFindedBrands[i].Name" />
        <!-- 根据BrandList的实际属性添加对应的隐藏字段 -->
    }

    <select asp-for="SelectedBrand" asp-items="@(new SelectList(@ViewBag.list,
                                            nameof(FindedBrand.Name),
                                            nameof(FindedBrand.Name)))"
            multiple="true" class="form-control brand-chosen">
    </select>

    <input type="submit" />
</form>

这种方式让表单提交时把集合数据作为POST参数传递,模型绑定能正确识别并填充AllFindedBrands属性。

方案2:用TempData暂存数据

在GET方法中将集合存入TempData,POST方法中取出反序列化:

控制器Search方法修改:

public async Task<IActionResult> Search(string Articul, int idClient)
{
    List<BrandList> findedBrands = new List<BrandList>();
    // 此处补充你的findedBrands填充逻辑
    var woDupes = // 你的去重逻辑
    ViewBag.list = woDupes;
    
    SearchViewModel model = new SearchViewModel();
    model.Articul = Articul;
    model.idClient = idClient;
    model.AllFindedBrands = new List<BrandList>(findedBrands);

    // 将集合序列化后存入TempData
    TempData["AllFindedBrands"] = JsonSerializer.Serialize(model.AllFindedBrands);

    return View(model);
}

SearchBrandResult方法修改:

[HttpPost]
public async Task<IActionResult> SearchBrandResult(SearchViewModel model)
{
    // 从TempData取出并反序列化集合
    if (TempData["AllFindedBrands"] is string json)
    {
        model.AllFindedBrands = JsonSerializer.Deserialize<List<BrandList>>(json);
    }

    return View();
}

注意:需确保BrandList类是可序列化的(无循环引用、有默认构造函数),且TempData仅保留一次请求生命周期的数据。

方案3:重新查询数据(推荐)

既然Articul和idClient能正常传递,直接在POST方法中根据这两个参数重新查询获取AllFindedBrands,避免前端传递大量数据的安全风险和绑定问题:

[HttpPost]
public async Task<IActionResult> SearchBrandResult(SearchViewModel model)
{
    // 根据Articul和idClient重新查询品牌数据
    List<BrandList> findedBrands = await YourDataService.GetBrands(model.Articul, model.idClient);
    model.AllFindedBrands = findedBrands;

    return View();
}

这种方式是最佳实践,既保证数据可靠性,也避免了前端篡改数据的风险。

额外优化

如果没有文件上传需求,建议去掉表单的enctype="multipart/form-data",使用默认的application/x-www-form-urlencoded即可,简化数据解析逻辑。

内容的提问来源于stack exchange,提问作者Serg.T.Russia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:50:26