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

ASP.NET Core中如何从视图向Get Action传递超3000条记录的List模型?

问题分析

你遇到的核心问题有两个:

  1. Get请求无法直接传递复杂模型:URL长度有限,且带外键关联的List<Product>无法被框架自动序列化为路由参数,直接通过asp-route-model或Url.Action传递@Model必然失败。
  2. TempData序列化异常:EF查询返回的Product是代理对象(带跟踪状态),无法直接被默认的TempData序列化机制处理,导致500错误。

以下是几种可行的解决方案,按推荐程度排序:


方案一:传递筛选条件而非完整模型(推荐)

直接传递大量数据到Get Action既不安全也不高效,最优方式是把生成产品列表的筛选参数传递给PrintProducts,在该Action中重新查询数据。

修改PrintProducts Action

public IActionResult PrintProducts(int side, MyViewModel myViewModel)
{
    List<Product> products;
    if (side == 0)
    {
        products = ShowAllProducts();
    }
    else
    {
        products = FilterProducts(myViewModel);
    }
    return View(products);
}

修改视图中的标签

传递筛选所需的参数(从ViewBag或页面上下文获取):

@model IEnumerable<Product>

<a title="Print" 
   asp-action="PrintProducts" 
   asp-route-side="@ViewBag.side"
   asp-route-categoryId="@ViewData["CategoryId"]"
   asp-route-priceRange="@ViewData["PriceRange"]">
    打印
</a>

如果MyViewModel参数较多,可拆分为单个路由参数传递,再在PrintProducts中重新构建MyViewModel执行筛选。


方案二:序列化模型后存入TempData(适合小量数据)

若必须传递完整模型,需先将Product列表序列化为可存储的格式(如JSON),同时避免EF代理对象的序列化问题。

步骤1:安装Newtonsoft.Json包

通过NuGet安装Newtonsoft.Json,用于处理复杂对象的序列化。

步骤2:修改第一个Action

using Newtonsoft.Json;

public IActionResult ShowProducts(int side, MyViewModel myViewModel)
{
    ViewBag.side = side;
    List<Product> products;

    if (side == 0)
    {
        // 关闭跟踪避免代理对象,或用ProjectTo映射为DTO
        products = ShowAllProducts().AsNoTracking().ToList();
    }
    else
    {
        products = FilterProducts(myViewModel).AsNoTracking().ToList();
    }

    // 序列化并存储到TempData,处理循环引用
    TempData["MyModel"] = JsonConvert.SerializeObject(products, new JsonSerializerSettings
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    });
    return View(products);
}

步骤3:修改PrintProducts Action

using Newtonsoft.Json;

public IActionResult PrintProducts()
{
    if (TempData["MyModel"] is string json)
    {
        var model = JsonConvert.DeserializeObject<List<Product>>(json);
        return View(model);
    }
    // 处理数据不存在的情况
    return RedirectToAction("ShowProducts");
}

⚠️ 注意:此方法不适合超大量数据,TempData依赖Session存储,有大小限制。


方案三:改用POST请求传递模型(适合必须传完整数据的场景)

Get请求不适合传递大量数据,可将标签改为表单提交,用POST方式传递模型。

视图代码

@model IEnumerable<Product>

<form asp-action="PrintProducts" method="post">
    @{ int i = 0; }
    @foreach (var product in Model)
    {
        <input type="hidden" name="model[@i].Id" value="@product.Id" />
        <input type="hidden" name="model[@i].Name" value="@product.Name" />
        <!-- 依次添加Product的其他属性隐藏字段 -->
        i++;
    }
    <button type="submit" title="Print">打印</button>
</form>

修改PrintProducts Action

[HttpPost]
public IActionResult PrintProducts(List<Product> model)
{
    return View(model);
}

⚠️ 注意:大量产品会生成过多隐藏字段,导致请求体过大,维护成本高。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 23:35:33