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

ASP.NET MVC Core:表格行文本框值从视图传至控制器的问题

问题解决:NewSerialNumber值无法传递到Controller的DownloadFile方法

问题描述

初始页面加载时NewSerialNumber为null,点击每行的Download按钮时,输入的NewSerialNumber文本框值无法传递到Controller的Action方法,始终为null,导致无法根据该值下载特定文件。

原因分析

  1. 使用<a>标签的@Url.Action生成链接时,item.newSerialNumber是页面加载时的初始值(null),不会实时获取用户在文本框中输入的新值。
  2. <a>标签发起的是GET请求,直接使用页面初始化时的参数生成URL,无法携带用户后续输入的动态值。

解决方案

方法一:使用表单POST提交(推荐)

将每行的下载操作改为表单提交,确保能携带当前行文本框的输入值。

视图代码修改:

@foreach (var item in Model)
{
    <tr>
        <td>@Html.DisplayFor(modelItem => item.ecuType)</td>
        <td>@Html.DisplayFor(modelItem => item.exp)</td>
        <td>@Html.DisplayFor(modelItem => item.ecuSft)</td>
        <td>
            <!-- 显式指定name属性,确保控制器能正确接收参数 -->
            @Html.TextBoxFor(modelItem => item.newSerialNumber, new { name = "newSerialNumber" })
        </td>
        <td>
            <!-- 为每行创建独立表单,提交到DownloadFile方法 -->
            <form method="post" asp-controller="TemDownload" asp-action="DownloadFile">
                <button type="submit" class="button">Download</button>
            </form>
        </td>
    </tr>
}

控制器代码修改:

将DownloadFile方法改为接收POST请求:

[HttpPost]
public IActionResult DownloadFile(string newSerialNumber)
{
    // 处理空值情况
    if (string.IsNullOrEmpty(newSerialNumber))
    {
        return BadRequest("请输入序列号");
    }

    // 根据newSerialNumber获取并返回文件
    // 示例:假设文件存储在wwwroot/files目录下
    var filePath = Path.Combine(_webHostEnvironment.WebRootPath, "files", $"{newSerialNumber}.pdf");
    
    if (System.IO.File.Exists(filePath))
    {
        byte[] fileBytes = System.IO.File.ReadAllBytes(filePath);
        return File(fileBytes, "application/pdf", $"{newSerialNumber}.pdf");
    }

    return NotFound("未找到对应文件");
}

方法二:使用JavaScript动态修改GET链接参数

如果需要保持GET请求方式,通过JavaScript实时获取文本框值并修改下载链接的参数。

视图代码修改:

@foreach (var item in Model)
{
    <tr>
        <td>@Html.DisplayFor(modelItem => item.ecuType)</td>
        <td>@Html.DisplayFor(modelItem => item.exp)</td>
        <td>@Html.DisplayFor(modelItem => item.ecuSft)</td>
        <td>
            <!-- 添加class和data属性用于JS定位 -->
            @Html.TextBoxFor(modelItem => item.newSerialNumber, new { @class = "serial-input", data-row-id = item.Id })
        </td>
        <td>
            <!-- 添加class和data属性,基础链接不带参数 -->
            <a href="@Url.Action("DownloadFile", "TemDownload")" class="download-button" data-row-id="@item.Id">Download</a>
        </td>
    </tr>
}

<!-- 添加JS脚本 -->
<script>
document.querySelectorAll('.download-button').forEach(btn => {
    btn.addEventListener('click', function(e) {
        e.preventDefault();
        const rowId = this.getAttribute('data-row-id');
        const input = document.querySelector(`.serial-input[data-row-id="${rowId}"]`);
        const serialNum = input.value.trim();

        if (!serialNum) {
            alert('请输入序列号');
            return;
        }

        // 构造带参数的新链接并跳转
        const baseUrl = this.getAttribute('href');
        const finalUrl = `${baseUrl}?newSerialNumber=${encodeURIComponent(serialNum)}`;
        window.location.href = finalUrl;
    });
});
</script>

控制器代码:

保持GET请求方式即可:

[HttpGet]
public IActionResult DownloadFile(string newSerialNumber)
{
    // 处理逻辑同方法一
}

关键注意事项

  • 确保文本框的name属性与控制器方法的参数名一致(方法一)。
  • 方法二中需处理空值校验,避免向控制器传递无效参数。
  • 如果模型是集合类型,TextBoxFor默认生成的name会带索引(如[0].newSerialNumber),需显式指定name为newSerialNumber才能让控制器直接接收单个字符串参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:47:14