【问题标题】:Asp.net MVC putting checkbox data in a list of booleansAsp.net MVC 将复选框数据放入布尔列表中
【发布时间】:2017-01-06 18:07:24
【问题描述】:

我正在尝试将未知数量的复选框绑定到布尔值列表。 经过数小时的搜索,我没有找到任何解决方案。

在我看来,这是代码的相关部分:

        @foreach (Device d in Data.GetDevices())
    {
        <label asp-for="NewRegistration.Devices">@d.Name</label>
        <input asp-for="NewRegistration.Devices" class="checkbox" type="checkbox" />
    }

循环有效,但是当我更改类型时,如果输入复选框,它给了我这个例外:

InvalidOperationException:意外的“asp-for”表达式结果类型“System.Collections.Generic.List`1[[System.Boolean, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e] ]' 为了 。如果 'type' 是 'checkbox',则 'asp-for' 必须是 'System.Boolean' 类型。

我尝试将数据放入的列表包含以下代码:

        private List<bool> _devices;

    public List<bool> Devices
    {
        get { return _devices; }
        set {_devices = value; }
    }

所以我的问题是如何将这些复选框中的值添加到我的布尔值列表中。当我没有指定输入的类型时,我没有收到任何错误,但输入的类型是文本。如果我在这些输入框中输入 true 或 false,我的代码就可以正常工作。但我想要一个复选框,而不是要求用户输入 true 或 false。

感谢您的宝贵时间!

编辑:我的问题很难解释。我正在验证表单并将其绑定到表示模型 PMRegistration 中定义的注册类的实例。如果sn-ps不够清晰,我会把完整的代码放在下面

注册类:

  public class Registration
{

    public int Id { get; set; }
    [Required(ErrorMessage = "required field")]
    [MaxLength(50, ErrorMessage = "To long")]
    [DisplayName("Name")]
    public string Name { get; set; }
    [Required(ErrorMessage = "required field")]
    [MaxLength(50, ErrorMessage = "To long")]
    [DisplayName("Firstname")]
    public string FirstName { get; set; }
    [Required(ErrorMessage = "required field")]
    [Range(1,110 ,ErrorMessage = "To long")]

    public string Age { get; set; }
    [Required(ErrorMessage = "required field")]
    [EmailAddress(ErrorMessage ="Not a valid email address")]
    public string Email { get; set; }
    [Required(ErrorMessage = "required field")]
    [DisplayName("slot1")]
    public int Slot1SessionId { get; set; }
    [Required(ErrorMessage = "required field")]
    [DisplayName("slot2")]
    public int Slot2SessionId { get; set; }
    [Required(ErrorMessage = "required field")]
    [DisplayName("slot3")]
    public int Slot3SessionId { get; set; }


    private List<bool> _devices;

    public List<bool> Devices
    {
        get { return _devices; }
        set {_devices = value; }
    }

    [Required(ErrorMessage = "required field")]
    [DisplayName("Organization")]
    public int OrganizationId { get; set; }
    public bool ClosingParty { get; set; }



}

我的观点是这样的:

        @using week3.Models;
@model week3.Models.PresentationModels.PMRegistration
<div>
    <h1>New Registration</h1>
    <h2>registration</h2>
</div>
<form class="form-group" asp-controller="Registration" asp-action="New" method="post">
    <div>
        <label asp-for="NewRegistration.Name">Name:</label>
        <input asp-for="NewRegistration.Name" class="form-control" value="@Model.NewRegistration.Name" />
        <span asp-validation-for="NewRegistration.Name" class="text-danger"></span>
    </div>
    <div>
        <label asp-for="NewRegistration.FirstName">Firstname:</label>
        <input asp-for="NewRegistration.FirstName" class="form-control" value="@Model.NewRegistration.FirstName" />
        <span asp-validation-for="NewRegistration.FirstName" class="text-danger"></span>
    </div>
    <div>
        <label asp-for="NewRegistration.Age">Age:</label>
        <input asp-for="NewRegistration.Age" class="form-control" value="@Model.NewRegistration.Age" />
        <span asp-validation-for="NewRegistration.Age" class="text-danger"></span>
    </div>
    <div>
        <label asp-for="NewRegistration.Email">Email:</label>
        <input asp-for="NewRegistration.Email" class="form-control" value="@Model.NewRegistration.Email" />
        <span asp-validation-for="NewRegistration.Email" class="text-danger"></span>
    </div>
    <div>
        <div>Pick your sessions</div>
        <label asp-for="NewRegistration.Slot1SessionId" class="form-label">Slot1:</label>
        <select asp-for="NewRegistration.Slot1SessionId" class="form-control" asp-items="@Model.getSessionNamesBySlot(1)" value="@Model.NewRegistration.Slot1SessionId"></select>
        <span asp-validation-for="NewRegistration.Slot1SessionId" class="text-danger"></span>
    </div>
    <div>
        <label asp-for="NewRegistration.Slot2SessionId">Slot2:</label>
        <select asp-for="NewRegistration.Slot2SessionId" class="form-control" asp-items="@Model.getSessionNamesBySlot(2)" value="@Model.NewRegistration.Slot2SessionId"></select>
        <span asp-validation-for="NewRegistration.Slot2SessionId" class="text-danger"></span>
    </div>
    <div>
        <label asp-for="NewRegistration.Slot3SessionId">Slot3:</label>
        <select asp-for="NewRegistration.Slot3SessionId" class="form-control" asp-items="@Model.getSessionNamesBySlot(3)" value="@Model.NewRegistration.Slot3SessionId"></select>
        <span asp-validation-for="NewRegistration.Slot3SessionId" class="text-danger"></span>
    </div>
    
        <div>are you wearing dangerous accessoires?</div>

        @foreach (Device d in Data.GetDevices())
        {
            
            <label asp-for="NewRegistration.Devices[0]">@d.Name</label>
            <input asp-for="NewRegistration.Devices[0]" class="checkbox" type="checkbox"  />
        }
    <div>
        <label asp-for="NewRegistration.OrganizationId">Organization:</label>
        <select asp-for="NewRegistration.OrganizationId" asp-items="@Model.getOrganizations()" class="form-control"></select><br />
    <span asp-validation-for="NewRegistration.OrganizationId" class="text-danger"></span>
    </div>
    <div>
        <label asp-for="NewRegistration.ClosingParty">Are you coming to the closing party?</label>
        <input asp-for="NewRegistration.ClosingParty" />
        <span asp-validation-for="NewRegistration.ClosingParty" class="text-danger"></span>
    </div>
            <input type="submit" class="btn btn-default" value="Register" />
</form>

【问题讨论】:

  • @foreach (Device d in Data.GetDevices()) 你是在 razor 中调用执行代码,而不是推送一个填充了数据的模型吗?
  • 不应该是 上的 asp-for="@d.NameOfBooleanProperty" 之类的吗?
  • 传递一个表示模型用于绑定。但数据是存储我的数据的地方。所以我让我的数据类中的所有设备循环遍历需要创建的复选框。

标签: asp.net-core-mvc


【解决方案1】:

错误原因

你的错误是因为你有这个:asp-for="NewRegistration.Devices"。这是无效的,因为标签是复选框类型的输入,所以 asp-for 期待一个布尔值,而您正在向它发送一个布尔值列表。

解决方案

这将为您的设备创建复选框:

@foreach (Device d in Data.GetDevices())
{
    @Html.CheckBox(item);
}

但我的假设是您希望用户选中这些复选框,然后将它们发回给您,如果是这种情况,那么您需要这样做:

你需要像这样创建一个模型:

public class Device
{
    public string Name { get; set; }
}
public class DevicesCollectionModel
{
    public List<Device> AvailableDevices { get; set; }
    public List<Device> SelectedDevices { get; set; }
}

填充DevicesCollectionModel.AvailableDevices 并将其传递给您的视图。 然后在您的视图中,为AvailableDevices 中的每个设备创建一个复选框。注意下面输入标签的name属性:

@foreach (var item in Model.AvailableDevices)
{
<div class="checkbox">
    <label>
        <input type="checkbox"
                name="SelectedDevices"
                value="@item.Name" /> @item.Name
        </label>
    </div>
}

然后在您的控制器中,在 post 中,您需要访问 SelectedDevices 属性来确定用户选择了什么。

此外,您可以创建单独的模型:一个用于发送给用户,一个控制器从用户接收。您传递给视图的模型可以只有AvailableDevices,而您在后期控制器中获得的模型可以有SelectedDevices。 MVC 将使用输入标签中的name 属性为您绑定它。

【讨论】:

  • 我意识到我描述我的问题的方式可能有点令人困惑。这些设备与列表的输出无关。如果您仍然感兴趣,我添加了完整的代码。
  • 你的意思是设备与代码的输出无关?您正在使用列表来创建复选框,那么它与它有什么关系呢?
  • 对不起,我没有得到你的代码!我认为您的代码是我没有正确阅读的解决方案!非常感谢!
  • 添加复选框列表和绑定选定值的绝对最佳答案。谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-08-05
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 2018-11-08
  • 2013-09-22
  • 2012-04-06
  • 1970-01-01
相关资源
最近更新 更多