Dav*_*ave 3 html c# asp.net-mvc razor
这是一个棘手的解释,所以我会尝试子弹指向.
问题:
我发现了什么:
只有在Razor代码中使用HTML Helpers时才会发生这种情况.如果我使用传统<input>元素(不理想),它工作正常.
题:
有没有人遇到过这个问题?或者有人知道为什么会这样,或者我做错了什么?
请查看下面的代码并感谢您查看我的问题!
控制器:
[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);
}
Run Code Online (Sandbox Code Playgroud)
Index.cshtml:
如您所见,我有"Make"和"Actual Make"输入.一个是HTML助手,另一个是传统的HTML输入.
@using (Html.BeginForm())
{
<div class="col-md-4">
@for (int i = 0; i < Model.Cars.Count; i++)
{
<div id="car-row-@i" class="form-group row">
<br />
<hr />
<label class="control-label">Make (@i)</label>
@Html.TextBoxFor(m => m.Cars[i].Make, new { @id = "car-make-" + i, @class = "form-control" })
<label class="control-label">Actual Make</label>
<input class="form-control" id="car-make-@i" name="Cars[@i].Make" type="text" value="@Model.Cars[i].Make" />
<div>
<input type="hidden" name="Cars.Index" value="@i" />
</div>
<br />
<button id="delete-btn-@i" type="button" class="btn btn-sm btn-danger" onclick="DeleteCarRow(@i)">Delete Entry</button>
</div>
}
<div class="form-group">
<input type="submit" class="btn btn-sm btn-success" value="Submit" />
</div>
</div>
}
Run Code Online (Sandbox Code Playgroud)
Javascript删除功能
function DeleteCarRow(id) {
$("#car-row-" + id).remove();
}
Run Code Online (Sandbox Code Playgroud)
用户界面中发生了什么:
小智 5
此行为的原因是HtmlHelper方法使用来自ModelState(如果存在)的值来设置value属性而不是实际的模型值.在TextBoxFor显示初始值的答案中解释了此行为的原因,而不是从代码更新的值.
在您的情况下,提交时,会添加以下值 ModelState
Cars[1].Make: Land Rover 2
Cars[2].Make: Audi 3
Cars[3].Make: Honda 4
Run Code Online (Sandbox Code Playgroud)
请注意,没有值,Cars[0].Make因为您删除了视图中的第一个项目.
当您返回视图时,该集合现在包含
Cars[0].Make: Land Rover 2
Cars[1].Make: Audi 3
Cars[2].Make: Honda 4
Run Code Online (Sandbox Code Playgroud)
因此,在循环的第一次迭代中,TextBoxFor()方法检查ModelState匹配,找不到,并生成value="Land Rover 2"(即模型值),您的手动输入也读取模型值和集value="Land Rover 2"
在第二次迭代中,TextBoxFor()确实找到匹配Cars[1]Make,ModelState因此它设置value="Land Rover 2"和手动输入读取模型值和集合value="Audi 3".
我假设这个问题是只是为了解释行为(在现实中,你会保存数据,然后重定向到GET方法来显示新的列表),但是当你通过调用返回的视图中可以产生正确的输出ModelState.Clear(),其将清除所有ModelState值,以便根据模型值TextBoxFor()生成value属性.
旁注:您的视图包含许多不良操作,包括用行为污染您的标记(使用Unobtrusive JavaScript),创建不表现为标签的标签元素(点击它们不会将焦点设置为关联控件),不必要的使用<br/>元素(使用css为元素设置边距等)和不必要的使用new { @id = "car-make-" + i }.循环中的代码可以是
@for (int i = 0; i < Model.Cars.Count; i++)
{
<div class="form-group row">
<hr />
@Html.LabelFor(m => m.Cars[i].Make, "Make (@i)")
@Html.TextBoxFor(m => m.Cars[i].Make, new { @class = "form-control" })
....
<input type="hidden" name="Cars.Index" value="@i" />
<button type="button" class="btn btn-sm btn-danger delete">Delete Entry</button>
</div>
}
$('.delete').click(function() {
$(this).closest('.form-group').remove();
}
Run Code Online (Sandbox Code Playgroud)