C# 使用HTML帮助程序时列表模型绑定索引不正确

C# 使用HTML帮助程序时列表模型绑定索引不正确,c#,html,asp.net-mvc,razor,C#,Html,Asp.net Mvc,Razor,这是一个很难解释的问题,所以我会试着用枪法来解释 问题: [HttpGet] public ActionResult Index() { List<Car> cars = new List<Car> { new Car { ID = 1, Make = "BMW 1", Model = "325" }, new Car { ID = 2, Make = "Land Ro

这是一个很难解释的问题,所以我会试着用枪法来解释

问题:

    [HttpGet]
    public ActionResult Index()
    {
        List<Car> cars = new List<Car>
        {
            new Car { ID = 1, Make = "BMW 1", Model = "325" },
            new Car { ID = 2, Make = "Land Rover 2", Model = "Range Rover" },
            new Car { ID = 3, Make = "Audi 3", Model = "A3" },
            new Car { ID = 4, Make = "Honda 4", Model = "Civic" }

        };

        CarModel model = new CarModel();
        model.Cars = cars;

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(CarModel model)
    {
        // This is for debugging purposes only
        List<Car> savedCars = model.Cars;

        return View(model);
    }
  • 查看时可供用户使用的动态行(集合)(添加/删除)
  • 用户删除行并保存(POST)
  • 使用非顺序索引传递回控制器的集合
  • 通过代码,一切看起来都很好,包括集合项、索引等
  • 呈现页面后,项目将无法正确显示-它们将全部显示为1,因此将在新的0位置复制顶部项目
  • 我的发现:

        [HttpGet]
        public ActionResult Index()
        {
            List<Car> cars = new List<Car>
            {
                new Car { ID = 1, Make = "BMW 1", Model = "325" },
                new Car { ID = 2, Make = "Land Rover 2", Model = "Range Rover" },
                new Car { ID = 3, Make = "Audi 3", Model = "A3" },
                new Car { ID = 4, Make = "Honda 4", Model = "Civic" }
    
            };
    
            CarModel model = new CarModel();
            model.Cars = cars;
    
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(CarModel model)
        {
            // This is for debugging purposes only
            List<Car> savedCars = model.Cars;
    
            return View(model);
        }
    
    只有在Razor代码中使用HTML帮助程序时才会发生这种情况。 如果我使用传统的
    元素(不理想),它工作得很好

    问题:

        [HttpGet]
        public ActionResult Index()
        {
            List<Car> cars = new List<Car>
            {
                new Car { ID = 1, Make = "BMW 1", Model = "325" },
                new Car { ID = 2, Make = "Land Rover 2", Model = "Range Rover" },
                new Car { ID = 3, Make = "Audi 3", Model = "A3" },
                new Car { ID = 4, Make = "Honda 4", Model = "Civic" }
    
            };
    
            CarModel model = new CarModel();
            model.Cars = cars;
    
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(CarModel model)
        {
            // This is for debugging purposes only
            List<Car> savedCars = model.Cars;
    
            return View(model);
        }
    
    以前有人遇到过这个问题吗?或者有人知道为什么会这样,或者我做错了什么

    请检查我下面的代码,谢谢检查我的问题

    控制器:

        [HttpGet]
        public ActionResult Index()
        {
            List<Car> cars = new List<Car>
            {
                new Car { ID = 1, Make = "BMW 1", Model = "325" },
                new Car { ID = 2, Make = "Land Rover 2", Model = "Range Rover" },
                new Car { ID = 3, Make = "Audi 3", Model = "A3" },
                new Car { ID = 4, Make = "Honda 4", Model = "Civic" }
    
            };
    
            CarModel model = new CarModel();
            model.Cars = cars;
    
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(CarModel model)
        {
            // This is for debugging purposes only
            List<Car> savedCars = model.Cars;
    
            return View(model);
        }
    
    用户界面中发生了什么:

        [HttpGet]
        public ActionResult Index()
        {
            List<Car> cars = new List<Car>
            {
                new Car { ID = 1, Make = "BMW 1", Model = "325" },
                new Car { ID = 2, Make = "Land Rover 2", Model = "Range Rover" },
                new Car { ID = 3, Make = "Audi 3", Model = "A3" },
                new Car { ID = 4, Make = "Honda 4", Model = "Civic" }
    
            };
    
            CarModel model = new CarModel();
            model.Cars = cars;
    
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(CarModel model)
        {
            // This is for debugging purposes only
            List<Car> savedCars = model.Cars;
    
            return View(model);
        }
    
    步骤1(删除行) 步骤2(提交表格)
    步骤3(结果)

    此行为的原因是
    HtmlHelper
    方法使用
    ModelState
    (如果存在)中的值来设置
    属性,而不是实际的模型值。此行为的原因已在对的答复中解释

    在您的情况下,提交时,以下值将添加到
    ModelState

    Cars[1].Make: Land Rover 2
    Cars[2].Make: Audi 3
    Cars[3].Make: Honda 4
    
    请注意,
    Cars[0]没有值。因为您删除了视图中的第一项,所以请生成

    返回视图时,集合现在包含

    Cars[0].Make: Land Rover 2
    Cars[1].Make: Audi 3
    Cars[2].Make: Honda 4
    
    因此,在循环的第一次迭代中,
    TextBoxFor()
    方法检查
    ModelState
    是否匹配,没有找到匹配项,并生成
    value=“Land Rover 2”
    (即模型值),您的手动输入也会读取模型值并设置
    value=“Land Rover 2”

    在第二次迭代中,
    TextBoxFor()
    确实在
    ModelState
    中找到了与
    Cars[1]Make
    匹配的,因此它设置
    value=“Land Rover 2”
    ,手动输入读取车型值并设置
    value=“Audi 3”

    我假设这个问题只是为了解释行为(实际上,您将保存数据,然后重定向到GET方法以显示新列表),但是您可以在返回视图时通过调用
    ModelState.Clear()
    来生成正确的输出,这将清除所有
    ModelState
    值,以便
    TextBoxFor()
    基于模型值生成
    属性

    旁注:您的视图包含很多不好的做法,包括使用行为(use)污染标记、创建不作为标签的标签元素(单击它们不会将焦点设置为关联控件)、不必要地使用

    元素(使用css为元素设置边距样式等)以及不必要地使用
    new{@id=“carmake-”+i}

    @for(int i=0;i
    @LabelFor(m=>m.Cars[i].Make,“Make(@i)”)
    @Html.TextBoxFor(m=>m.Cars[i].Make,new{@class=“form control”})
    ....
    删除条目
    }
    $('.delete')。单击(函数(){
    $(this).closest('.form group').remove();
    }
    
    在您的POST方法中,在
    返回视图(模型);
    之前添加
    ModelState.Clear();
    。如果这样解决了问题,则表明与删除项目相关的代码是错误的。@StephenMuecke非常感谢您的回复。添加
    ModelState.Clear()
    成功了!我现在已将用于删除行的JQuery添加到我的OP中。你知道我缺少了什么吗?删除行后,我是否需要在此函数中以某种方式更新模型?精彩的解释。这对我帮助很大,我非常感谢你花时间对我的标记进行评论。