asp.net mvc视图仅在使用for循环时返回

时间:2017-04-11 13:58:07

标签: c# asp.net-mvc asp.net-mvc-4 razor data-binding

所以本周我一直在研究一个简单的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

3 个答案:

答案 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