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

Html.BeginForm传递多对象时参数值重复的问题及解决方法

解决Razor视图中Post多个Adress对象时参数绑定重复的问题

这个问题的核心在于ASP.NET MVC模型绑定的工作逻辑,以及你当前Razor视图生成的HTML输入元素存在name属性重复的问题——模型绑定器无法区分哪个值对应控制器的model参数,哪个对应model1参数,最终导致两个参数拿到完全相同的值。

问题根源拆解

你原来的视图代码中,@Html.TextBoxFor(model => model.Number)会生成一个name="Number"的输入框,而@Html.TextBoxFor(model1 => model1.Number)同样会生成name="Number"的输入框。当表单提交时,浏览器会将两个同名参数发送到服务器,但模型绑定器无法区分归属,会把同一个值同时绑定到model.Number和model1.Number上,这就是你看到两个对象值完全相同的原因。

推荐解决方案:使用视图模型(ViewModel)

这是ASP.NET MVC处理复杂表单场景的最佳实践,通过创建一个专门的视图模型来封装你需要的两个Adress对象,让模型绑定器能清晰识别每个参数的归属。

步骤1:创建视图模型类

在项目中新增一个包含两个Adress属性的视图模型:

public class AdressPairViewModel
{
    // 存储原始地址信息
    public Adress OriginalAdress { get; set; }
    // 存储新地址信息
    public Adress NewAdress { get; set; }
}

步骤2:修改Razor视图

将视图的模型类型改为AdressPairViewModel,并通过强类型表达式生成正确的name属性:

@model AdressPairViewModel

@using (Html.BeginForm("chAdress", "Adress", FormMethod.Post)) {
    <h4>原始地址</h4>
    @Html.LabelFor(model => model.OriginalAdress.Number)
    @Html.TextBoxFor(model => model.OriginalAdress.Number)
    @Html.ValidationMessageFor(model => model.OriginalAdress.Number)
    
    @Html.LabelFor(model => model.OriginalAdress.Distance)
    @Html.TextBoxFor(model => model.OriginalAdress.Distance)
    @Html.ValidationMessageFor(model => model.OriginalAdress.Distance)

    <h4>新地址</h4>
    @Html.LabelFor(model => model.NewAdress.Number)
    @Html.TextBoxFor(model => model.NewAdress.Number)
    @Html.ValidationMessageFor(model => model.NewAdress.Number)
    
    @Html.LabelFor(model => model.NewAdress.Distance)
    @Html.TextBoxFor(model => model.NewAdress.Distance)
    @Html.ValidationMessageFor(model => model.NewAdress.Distance)

    <button type="submit">修改地址</button>
}

此时生成的输入框name属性会是OriginalAdress.Number和NewAdress.Number,模型绑定器能准确区分归属。

步骤3:修改控制器方法

将控制器的参数改为接收AdressPairViewModel:

public void chAdress(AdressPairViewModel viewModel)
{
    prepareConnection();
    string distance = viewModel.OriginalAdress.Distance.ToString();
    string newDistance = viewModel.NewAdress.Distance.ToString();
    Dictionary<string, object> queryDict = new Dictionary<string, object>();
    queryDict.Add("distance", distance);
    queryDict.Add("newDistance", newDistance);
    var query = new Neo4jClient.Cypher.CypherQuery(
        "start n=node(*) where (n:Adress) and exists(n.distance) and n.distance =~ {distance} set n.distance = {newDistance} return n", 
        queryDict, 
        CypherResultMode.Set
    );
    List<Adress> adrese = ((IRawGraphClient)client).ExecuteGetCypherResults<Adress>(query).ToList();
}

备选方案:手动指定输入框name属性

如果不想创建视图模型,也可以直接手动指定输入框的name属性,让模型绑定器识别对应参数:

@using (Html.BeginForm("chAdress", "Adress", FormMethod.Post)) {
    @Html.Label("Number")
    @Html.TextBox("model.Number", Model?.Number)
    @Html.ValidationMessage("model.Number")
    
    @Html.Label("Distance")
    @Html.TextBox("model.Distance", Model?.Distance)
    @Html.ValidationMessage("model.Distance")

    @Html.Label("New Number")
    @Html.TextBox("model1.Number")
    @Html.ValidationMessage("model1.Number")
    
    @Html.Label("New Distance")
    @Html.TextBox("model1.Distance")
    @Html.ValidationMessage("model1.Distance")

    <button type="submit">修改地址</button>
}

这种方式无需修改控制器,但强类型支持和验证体验不如视图模型方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:02:35