所以本周我一直在研究一个简单的asp.net应用程序。今天我有一个剃刀视图的问题,没有返回任何控制器方法。视图必须返回List<>。
中的多个对象我终于通过将一个对象列表传递给视图并使用'for'循环遍历它们来实现它。我今天也尝试了一个foreach循环但是没有用。
我有以下GET方法将空对象列表传递给视图:
// GET: MpSwitches/CreateSeveral
public ActionResult CreateSeveral()
{
var mpSwitches = new List<MpSwitch>
{
new MpSwitch() {IpAdress = "1"},
new MpSwitch() {IpAdress = "2"},
new MpSwitch() {IpAdress = "3"},
new MpSwitch() {IpAdress = "4"},
new MpSwitch() {IpAdress = "5"}
};
// Check if the user gets redirected to this method because of a First Time Startup.
if (TempData["RedirectFirstTimeStartup"] != null)
{
ViewBag.FirstTime =
"Je bent doorgestuurd naar deze pagina omdat er nog geen MP-switches in de database staan.";
return View(mpSwitches);
}
return View(mpSwitches);
}
然后是视图:
@model List<WebInterface.Models.MpSwitch>
@{
ViewBag.Title = "Create several";
}
<h2>Create several</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>MpSwitch</h4>
@if (ViewBag.FirstTime != null)
{
<div class="alert-warning">
<b>Opgelet! </b>@ViewBag.FirstTime
</div>
}
@for (int i = 0; i < Model.Count; i++)
{
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model[i].IpAdress, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model[i].IpAdress, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model[i].IpAdress, "", new { @class = "text-danger" })
</div>
</div>
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
我的问题是:为什么这个相同的代码不能使用'foreach'而不是'for'循环?
目前无效的代码:
@foreach (var item in Model)
{
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger"})
<div class="form-group">
@Html.LabelFor(modelItem => item.IpAdress, htmlAttributes: new {
@class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(modelItem => item.IpAdress, new {
htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(modelItem => item.IpAdress, "", new
{ @class = "text-danger" })
</div>
</div>
}
现在使用foreach循环时,以下控制器方法不会获取参数(参数为null)。
// POST: MpSwitches/CreateSeveral
// To protect from overposting attacks, please enable the specific
properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateSeveral([Bind(Include =
"Id,IpAdress,LastSyncDateTime")] List<MpSwitch> mpSwitches)
{
if (ModelState.IsValid)
{
foreach (var mpSwitch in mpSwitches)
{
db.MpSwitches.Add(mpSwitch);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(mpSwitches);
}
我收到以下错误:Link to image of my error
答案 0 :(得分:0)
您没有得到的原因是,当您使用foreach
而不是for
时,您没有该项的索引,并且HTML元素的名称/ ID重叠彼此。看一下您发送到浏览器的HTML源代码(查看页面源或检查元素),您会注意到名称是MpSwitch[0].IpAddress
等。当您使用foreach
时它只会是MpSwitch.IpAddress
。这不能序列化为集合。
答案 1 :(得分:0)
MVC ModelBinder需要列表项的索引才能正确地将它们绑定到ViewModel。
如果您使用for
循环,则正确的索引会合并到生成的HTML id
元素的name
和<input>
属性中。
您还可以明确合并索引,请参阅Binding arrays with missing elements in asp.net mvc。
答案 2 :(得分:0)
如果你在使用foreach loop
时查看渲染的html,你会得到这个
<input class="form-control text-box single-line" id="item_IpAdress" name="item.IpAdress" value="" type="text">
当您使用for loop
时,它就像这样
<input class="form-control text-box single-line" id="MpSwitch_0__IpAdress" name="MpSwitch[0].IpAdress" value="" type="text">
因为您使用的是List<MpSwitch>
所以当您在for loop
中使用MpSwitch[0].IpAdress
提交表单时,IpAddress
的新值将被MpSwitch
分配给index 0
1}} foreach loop
值将被分配给item.IpAdress
,当您提交List<MpSwitch>
时将null
因为要绑定复杂对象,您必须为每个{1}}提供一个索引项目。您也可以查看Model Binding To A List