MVC CheckBoxList 模型绑定与非布尔值

Posted

技术标签:

【中文标题】MVC CheckBoxList 模型绑定与非布尔值【英文标题】:MVC CheckBoxList model binding with non boolean 【发布时间】:2015-02-17 01:16:59 【问题描述】:

我想将一个 List 绑定到 CheckBox 并获取选定的值。我需要显示两个这样的 Checkbox 表,并且必须检索这两个 ID。

下面是我的视图模型

public partial class ViewModel_Role_Security

    public List<Roles> oRoleMaster  get; set; 
    public List<Securities> oSecurityMaster  get; set; 


这三个都有这两个值 1.身份证 2. 名称(在这种情况下,对于角色 - ID、角色名称 | 对于证券 - ID、安全名称 ...) //添加 bool 类型的第三个属性 isselected 以便仅在复选框中工作,然后您将返回它 这些有任何布尔

通过使用此 ViewModel,我将使用以下方法绑定这些项目...

public ActionResult AddingRoleSecurity()
        
    ListRoles = new List<Roles>();
    ListSecurities = new List<Securities>();  //And then populate them with data ...

    var model = new ViewModel_Role_Security();
    model.oRoleMaster = ListRoles;
    model.oSecurityMaster = ListSecurities;
    return View(model);

我对应的cshtml文件是..

@model KnackWFM.BusinessEntities.ViewModel_Role_Security

@using (Html.BeginForm())

    <div class="contentsecurity">

        <div class="User_role">
            <p class="Security_role">User Role</p>

            @for (int i = 0; i < Model.oRoleMaster.Count; i++)
            
                <input id="@Model.oRoleMaster[i].RoleID" name="@Model.oRoleMaster[i].RoleName" type="checkbox" value="@(Model.oRoleMaster[i].RoleName)" />
                <label for="@Model.oRoleMaster[i].RoleID">@Model.oRoleMaster[i].RoleName</label>
                <br />
                @Html.CheckBoxFor(Model.oRoleMaster[i].RoleID.selec)
            

        </div>

        <div class="User_Page">
            <p class="Security_role">Role Security</p>

            @for (int i = 0; i < Model.oSecurityMaster.Count; i++)
            
                <input id="@Model.oSecurityMaster[i].SecurityID" name="@Model.oSecurityMaster[i].SecurityName" type="checkbox" value="@(Model.oSecurityMaster[i].SecurityName)" />
                <label for="@Model.oSecurityMaster[i].SecurityID">@Model.oSecurityMaster[i].SecurityName</label>
                <br />
            

        </div>
        <div class="bottombuttonsecurity">
            <button type="submit" id="btnSave" name="Command" value="Save" style="background-color: #3d3c4c;border-radius: 8px;color: white;padding: 5px;border: 1px solid #3d3c4c;">Save</button>
        </div>
    </div>

为此我得到以下输出,

我希望将检查的值作为模型。

我有一个这样的 HttpPost 方法,但它返回空值。

[HttpPost]
public ActionResult AddingRoleSecurity(ViewModel_Role_Security model)

    return View();

请告诉我如何获取模型中的签入值?

非常感谢!

【问题讨论】:

复选框值怎么可以是字符串类型?复选框值应始终为真或假。为什么要将字符串类型绑定到复选框? 在 AdditionalRoleSecurity 操作方法中,您提到了模型为 ViewModel_Role_Security 并且在您的视图中您提到模型名称为 ViewModel_User_Role_Security_Page 那些拖车彼此不匹配这是我认为的问题 嗨,我想从选择中获取选定的 IdS。当模型没有任何布尔值时,我将如何设置模型的值 @Aravindan 谢谢,那是一个错字……那不是问题 使用包含bool IsSelected 属性的RolesSecurities 的视图模型,以便您可以在集合中正确使用强类型帮助器 【参考方案1】:

只是为了充实我上面的评论......

对于 checkboxList - viewmodel 应该包括标识符属性和布尔选择属性。如果还没有,则扩展或创建新的 ViewModel 类来实现此目的 - 将现有模型映射到此特定视图模型。

即- 你的模型类

public class UserRole

  public int RoleID get; set;
  public string RoleName get; set;
  public bool Selected get; set;


public class UserSecurity

  public int SecurityID get; set;
  public string SecurityName get; set;
  public bool Selected get; set;


public class UserRoleAndSecurityModel

  public List<UserRole> RoleMaster get; set;
  public List<UserSecurity> SecurityMaster get; set;

您的观点: 请注意,除了 Html.HiddenFor() 复选框之外,每个 UserRole/UserSecurity ID 属性都包含在内,这允许 MVC 在回发后绑定 ID 属性。

@model UserRoleAndSecurityModel   

@using (Html.BeginForm())

    <div class="contentsecurity">  
        <div class="User_role">
            <p class="Security_role">User Role</p>

            @for (int i = 0; i < Model.RoleMaster.Count; i++)
            
                @Html.CheckBoxFor(m => m.RoleMaster[i].Selected)
                @Html.HiddenFor(m => m.RoleMaster[i].RoleId)
                @Html.LabelFor(m => m.RoleMaster[i].Selected, 
                                    Model.RoleMaster[i].RoleName)
                <br />
            
        </div>

        <div class="User_Page">
            <p class="Security_role">Role Security</p>

            @for (int i = 0; i < Model.SecurityMaster.Count; i++)
            
                @Html.CheckBoxFor(m => m.SecurityMaster[i].Selected)
                @Html.HiddenFor(m => m.SecurityMaster[i].SecurityId) 
                @Html.LabelFor(m => m.SecurityMaster[i].Selected, 
                                    Model.SecurityMaster[i].SecurityName)
                <br />

            
        </div>
        <div class="bottombuttonsecurity">
            <button type="submit" id="btnSave" name="Command" value="Save" style="background-color: #3d3c4c;border-radius: 8px;color: white;padding: 5px;border: 1px solid #3d3c4c;">Save</button>
        </div>
    </div>

你的控制器现在也应该使用上面的新模型了!

【讨论】:

非常感谢您抽出宝贵时间,我的问题是角色和证券是实体模型。我不应该为了改变这些而改变我的桌子。所以我的问题是这样的。如果我误导了任何地方,我很抱歉......再次感谢! 您不应该总是期望能够将实体框架类直接绑定到视图 - MVC 模型应该包含具有与视图交换信息的属性。创建仅用于单个视图的模型是完全可以接受的,并让您的控制器创建一个新实例,然后从实体框架模型映射所需的属性【参考方案2】:

我不想显得我在为 James 的出色工作而受到赞扬,但我能做的只有一个新的答案。由于我不明白的原因,我纠正代码中的编译错误的编辑被拒绝,因为没有纠正关键问题。因此,我将其发布为完整的工作答案。

模型:

public class UserRole

  public int RoleID get; set;
  public string RoleName get; set;
  public bool Selected get; set;


public class UserSecurity

  public int SecurityID get; set;
  public string SecurityName get; set;
  public bool Selected get; set;


public class UserRoleAndSecurityModel

  public List<UserRole> RoleMaster get; set;
  public List<UserSecurity> SecurityMaster get; set;

还有观点:

@model UserRoleAndSecurityModel   

@using (Html.BeginForm())

    <div class="contentsecurity">  
        <div class="User_role">
            <p class="Security_role">User Role</p>

            @for (int i = 0; i < Model.RoleMaster.Count; i++)
            
                @Html.CheckBoxFor(m => m.RoleMaster[i].Selected)
                @Html.HiddenFor(m => m.RoleMaster[i].RoleId)
                @Html.LabelFor(m => m.RoleMaster[i].Selected, 
                                    Model.RoleMaster[i].RoleName)
                <br />
            
        </div>

        <div class="User_Page">
            <p class="Security_role">Role Security</p>

            @for (int i = 0; i < Model.SecurityMaster.Count; i++)
            
                @Html.CheckBoxFor(m => m.SecurityMaster[i].Selected)
                @Html.HiddenFor(m => m.SecurityMaster[i].SecurityId) 
                @Html.LabelFor(m => m.SecurityMaster[i].Selected, 
                                    Model.SecurityMaster[i].SecurityName)
                <br />

            
        </div> 

        <div class="bottombuttonsecurity">
            <button type="submit" id="btnSave" name="Command" value="Save" style="background-color: #3d3c4c;border-radius: 8px;color: white;padding: 5px;border: 1px solid #3d3c4c;">Save</button>
        </div>
    </div>

【讨论】:

【参考方案3】:

我会使用https://www.nuget.org/packages/BeginCollectionItem/

这将帮助您使用 GUID 获得正确的绑定顺序

最好的问候 布林

【讨论】:

【参考方案4】:

你应该为你的两个模型添加第三个 bool 属性,

  public bool IsSelected  get; set; 

并将其设置为默认为 false,当您选中相应的复选框时,将在回发时将其设为 true, 并且根据真实值,您也可以使用相应的选定值和文本做任何您想做的事情

这是我的代码,我用过一些地方来达到同样的效果:

                    <td colspan="4" style="-webkit-column-count: 3; -moz-column-count:3; -ms-column-count:3; -o-column-count: 3; column-count: 3">
                        @int i = 0;
                        
                        @foreach (var item in Model.SurfaceTypeList)
                        

                            <input name="SurfaceTypeList[@i].Text" type="hidden" value="@item.Text" />
                            <input name="SurfaceTypeList[@i].Value" type="hidden" value="@item.Value" />
                            <input data-val="true" id="SurfaceTypeList_@(i)__IsSelected" name="SurfaceTypeList[@i].IsSelected" type="checkbox" class="SurfaceType" value="true" checked="@item.IsSelected" />
                            @Html.Label(item.Text)
                            <br /><br />
                            i++;
                        


                    </td>
                    <td colspan="2"></td>

模型包含一个属性:

public List<SurfaceType> SurfaceTypeList  get; set; 
public class SurfaceType

public bool IsSelected  get; set; 
    public string Text  get; set; 
    public string Value  get; set; 

这是我检索文本/值的方式:

  foreach (var item in modelData.SurfaceTypeList)
            
                if (item.IsSelected)
                
                    var surfaceType = new XElement("SurfaceType");
                    var id = new XElement("Id");
                    id.Add(item.Value);
                    surfaceType.Add(id);
                    var i = id.Value;
                    surfaceTypeList.Add(surfaceType);
                

            

【讨论】:

当我返回相同的模型时,我只是看到选择的布尔值[true/false]。如何获取对应的ID值? 检查 google chrome 中的 html 以检查您获得的 id 类型

以上是关于MVC CheckBoxList 模型绑定与非布尔值的主要内容,如果未能解决你的问题,请参考以下文章

mvc 绑定/发布布尔到单选按钮

.NET MVC3中扩展一个HtmlHelper方法CheckBoxList

为啥被删除:ASP.NET MVC CheckBoxList(没有 MVCContrib)

MVC3 View 中的 CheckboxList 并获取传递给控制器​​的选中项

MVC 5 Razor 视图未将 bool 绑定到输入

MVC 模型布尔显示是或否