复选框列表 MVC 部分

Checkboxlist MVC Partial

我有以下视图模型代码:

public class TestCheckboxlistParentModel
{
    public TestCheckboxlistParentModel()
    {
        CBL = new TestCheckboxlistModel();
    }
    public TestCheckboxlistModel CBL { get; set; }
}

public class TestCheckboxlistModel
{
    public string TextField { get; set; }
    public IList<string> SelectedFruits { get; set; }
    public IList<SelectListItem> AvailableFruits { get; set; }

    public TestCheckboxlistModel()
    {
        SelectedFruits = new List<string>();
        AvailableFruits = new List<SelectListItem>();
    }
}

控制器:

    public ActionResult TestCheckboxlist()
    {
        var model = new TestCheckboxlistParentModel
        {
            CBL = new TestCheckboxlistModel()
            {
                AvailableFruits = GetFruits()
            }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult TestCheckboxlist(TestCheckboxlistParentModel model)
    {
        if (ModelState.IsValid)
        {
            // Save data to database, and redirect to Success page.

            return RedirectToAction("Success");
        }
        //model.AvailableFruits = GetFruits();
        return View(model);
    }

    public ActionResult Success()
    {
        return View();
    }

    private IList<SelectListItem> GetFruits()
    {
        return new List<SelectListItem>
    {
        new SelectListItem {Text = "Apple", Value = "1"},
        new SelectListItem {Text = "Pear", Value = "2"},
        new SelectListItem {Text = "Banana", Value = "3"},
        new SelectListItem {Text = "Orange", Value = "4"},
        };
    }

局部视图:

@model Web.ViewModels.TestCheckboxlistModel

<div class="form-group">
    @Html.LabelFor(model => model.TextField)
    <div class="col-md-10">
        @Html.EditorFor(model => model.TextField)
    </div>
</div>

    @foreach (var item in Model.AvailableFruits)
    {
<div class="checkbox">
    <label>
        <input type="checkbox"
               name="@Html.IdFor(p=>p.SelectedFruits)"
               value="@item.Value" /> @item.Text
        </label>
    </div>
    }

查看:

@model Web.ViewModels.TestCheckboxlistParentModel

@{
    ViewBag.Title = "TestCheckboxlist";
    Layout = "~/Views/Shared/_LayoutApplicationDriver.cshtml";
}

@using (Html.BeginForm())
{

    @Html.Partial("TestPartialCheckboxlist", Model.CBL, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "CBL" } })
    <div class="form-group text-center">
        <input type="submit" class="btn btn-primary" value="Submit" />
    </div>
}

问题是 SelectedFruits 在 post 方法中始终没有任何元素。如果我不使用嵌套的局部视图,相同的代码可以正常工作。 属性 TextField 可以与 Partial

一起正常工作

PS。这不是 问题的重复。这个问题是我回答的基础。就我而言,我需要在部分视图中显示复选框列表,但它不起作用!

您使用 name="@Html.IdFor(p => p.SelectedFruits)" 生成 name="CBL_SelectedFruits",但为了绑定到您的模型,您需要 name="CBL.SelectedFruits"(注意 . 点,而不是 _ 下划线),您可以使用

生成
name="@Html.NameFor(p => p.SelectedFruits)"

但是您的代码还有其他问题。你没有与你的模型强绑定,你没有得到验证,你在不需要时为 属性 AvailableFruits 生成 IList<SelectListItem> (它可能只是 IList<string> AvailableFruits,最重要的是,如果您 return 视图,用户选中的所有复选框都会丢失(所有复选框都将取消选中)。

更改您的视图模型,以便您可以强绑定到您的属性

public class FruitVM
{
    public string Name { get; set; }
    public bool IsSelected { get; set; }
}
public class ParentVM
{
    public string TextField { get; set; }
    public List<FruitVM> Fruits { get; set; }
}

并在 GET 方法中

ParentVM model = new ParentVM
{
    Fruits = new List<FruitVM>{ 
        new FruitVM{ Name = "Apple" },
        new FruitVM{ Name = "Pear" }, 
        ....       
    }
};
return View(model);

并为 FruitVM 创建一个 EditorTemplate - 在 /Views/Shared/EditorTemplates/FruitVM.cshtml

@model FruitVM
@Html.CheckBoxFor(m => m.IsSelected)
@Html.LabelFor(m => m.IsSelected, Model.Name)

并在视图中

@Html.ParentVM
....
@using (Html.BeginForm())
{
    @Html.LabelFor(m => m.TextField)
    @Html.EditorFor(m => m.TextField)

    @Html.EditorFor(m => m.Fruits)

    <input type="Submit" value="Save" />
}

EditorFor() 方法将为 collection 中的每个项目生成正确的 html。

然后在POST方法中,可以用

获取选中的item
[HttpPost]
public ActionResult TestCheckboxlist(ParentVM model)
{
    ....
    List<string> selectedFruits = model.Fruits.Where(x => x.IsSelected);