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

如何在CSHTML中将含列表与参数的ViewModel绑定到控制器Action

问题描述

我有如下包含列表和嵌套类的ViewModel:

public class MyViewModel
{
    public List<Guid> Ids{ get; set; }

    public History HistoryRecord{ get; set; }
}

public class History
{
    public string UserName{ get; set; }
    public string Email{ get; set; }
}

需要将上述数据提交到以下控制器Action:

public async Task<IActionResult> myAction([Bind("Ids","UserName","Email")] MyViewModel viewModel)
{
    // 业务逻辑
}

我通过以下输入框获取UserName和Email的值:

<input type="text" class="form-control child " name="name" id="nameTextbox" placeholder="name" required />
<input type="text" class="form-control child " name="email" id="emailTextbox" placeholder="email" required />

尝试用Url.Action实现数据提交但未成功,不清楚如何传递多值:

<button type="submit" class="btn btn-primary" id="confirm" onclick="location.href='@Url.Action("myAction","myController", values: new {Ids= @Model.Ids.ToList(), Name = ? , Emil = ? })'">confirm</button>
解决方案

方式一:表单提交(推荐)

这是ASP.NET Core中处理复杂模型提交的常规方案,能自动完成模型绑定:

  1. 修正输入框的name属性
    要匹配Action中Bind指定的字段名,把输入框的name改成UserName和Email:
<input type="text" class="form-control child" name="UserName" id="nameTextbox" placeholder="name" required />
<input type="text" class="form-control child" name="Email" id="emailTextbox" placeholder="email" required />
  1. 添加隐藏字段传递Ids列表
    为每个Guid生成一个隐藏输入框,名称设为Ids,表单提交时会自动绑定到ViewModel的Ids列表:
@foreach (var id in Model.Ids)
{
    <input type="hidden" name="Ids" value="@id.ToString()" />
}
  1. 用表单包裹控件并提交
    不需要用onclick跳转,直接通过表单指定目标Action:
<form asp-action="myAction" asp-controller="myController" method="post">
    <input type="text" class="form-control child" name="UserName" id="nameTextbox" placeholder="name" required />
    <input type="text" class="form-control child" name="Email" id="emailTextbox" placeholder="email" required />
    
    @foreach (var id in Model.Ids)
    {
        <input type="hidden" name="Ids" value="@id.ToString()" />
    }
    
    <button type="submit" class="btn btn-primary" id="confirm">confirm</button>
</form>

提示:POST请求比GET更适合传递复杂数据,避免列表参数的格式问题。

方式二:AJAX提交(无刷新场景)

如果需要页面不刷新提交数据,可以用JavaScript收集数据后发送AJAX请求:

  1. 保留输入框和按钮(移除onclick)
<input type="text" class="form-control child" name="UserName" id="nameTextbox" placeholder="name" required />
<input type="text" class="form-control child" name="Email" id="emailTextbox" placeholder="email" required />
<button type="button" class="btn btn-primary" id="confirm">confirm</button>
@Html.AntiForgeryToken() <!-- 添加防伪令牌,防止跨站伪造请求 -->
  1. 编写JavaScript提交逻辑
    收集输入框值和Ids列表,通过POST请求提交到Action:
document.getElementById('confirm').addEventListener('click', function() {
    // 组装提交数据
    var data = {
        Ids: @Json.Serialize(Model.Ids),
        UserName: document.getElementById('nameTextbox').value,
        Email: document.getElementById('emailTextbox').value
    };

    // 发送AJAX请求
    fetch('@Url.Action("myAction", "myController")', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
        },
        body: JSON.stringify(data)
    })
    .then(response => response.json())
    .then(result => {
        // 处理返回结果
        console.log(result);
    })
    .catch(error => {
        console.error('提交失败:', error);
    });
});

你之前的方式失败原因

  • Url.Action是服务器端渲染生成的,无法获取客户端输入框的动态值(用户输入的名称、邮箱),所以没法直接在values参数里填写这些内容。
  • GET请求传递列表参数需要特殊格式(比如Ids[0]、Ids[1]),用Url.Action生成会非常繁琐,POST请求则不需要额外处理列表的格式问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:15:36