如何 HTTPPost ASP.Net MVC 5 CheckBoxList 到数据库

How to HTTPPost ASP.Net MVC 5 CheckBoxList to database

我无法从复选框列表中获取 post 的值到我的数据库 table。这是我的模型:

public partial class SecurityChange_Access
{
    public int ID { get; set; }
    public string Access_Name { get; set; }
    public bool IsSelected { get; set; }
}

public partial class Change
{
    public int ID { get; set; }
    public string Emp_FirstName { get; set; }
    public string Emp_LastName { get; set; }
    public string Emp_Supervisor { get; set; }
    public string Emp_MangerEmail { get; set; }
    public string Emp_MirrorAccount { get; set; }
    public string Security_Change_Access { get; set; }

    public List<SecurityChange_Access> SecurityAccessList { get; set; }

    public bool addAccess { get; set; }
    public IEnumerable<SelectListItem> ChangeRadioList { get; set; }

    //[Required(ErrorMessage = "You must select an option for TestRadio")]
    public String ChangeRadio { get; set; }
}

public class bTest
{
    public int ID { get; set; }
    public string Name { get; set; }
}

这是 HTTPGet 和 HTTPPost:

[HttpGet]
public ActionResult Change(Change change)
{   
    List<bTest> list = new List<bTest>();
    list.Add(new bTest() { ID = 1, Name = "Add Access" });
    list.Add(new bTest() { ID = 2, Name = "Remove Access" });
    list.Add(new bTest() { ID = 3, Name = "Change Access" });
    SelectList sl = new SelectList(list, "Name", "Name");
    change.ChangeRadioList = sl;

    List<ActiveDirectory> objadlist = (from data in       objentity.ActiveDirectories select data).ToList();
    ActiveDirectory objAD = new ActiveDirectory();
    objAD.displayName = "";
    objAD.mail = "";
    objAD.Id = 0;
    objadlist.Insert(0, objAD);
    SelectList objmodeldata = new SelectList(objadlist, "displayName", "displayName", 0);
    /*Assign value to model*/
    change.ADList = objmodeldata;

    change.SecurityAccessList = new List<SecurityChange_Access>();
    change.SecurityAccessList = BindSecurity();

    return View(change);
}

public List<SecurityChange_Access> BindSecurity()
{
    List<SecurityChange_Access> _objsecurity = (from data in _entities.SecurityChange_Access select data).ToList();
    return _objsecurity;
}

[HttpPost]
public ActionResult Change([Bind(Include = "ID, Emp_FirstName, Emp_LastName, Emp_Supervisor, Emp_MangerEmail, Emp_MirrorAccount, Security_Change_Access, Security_Access_To_1, Security_Access_To_2, Security_Access_To_3, Security_Access_To_4, Security_Access_To_5, Security_Access_To_6, Security_Access_To_7, Security_Access_To_8, Security_Access_To_9, Security_Access_To_10, Security_Access_To_Other, Security_Access_ADF_Mirror, Security_Access_JDE_Mirror, Security_Access_NetworkDrives_1, Security_Access_NetworkDrives_2, Security_Access_NetworkDrives_3, Security_Access_NetworkDrives_4, Security_Access_NetworkDrives_5, Security_Access_NetworkDrives_6, Security_Access_NetworkDrives_7, Security_Access_NetworkDrives_8, Security_Access_NetworkDrives_9, Security_Access_NetworkDrives_10, Security_Access_NetworkDrives_11, Security_Access_NetworkDrives_12, Security_Access_NetworkDrives_13, Security_Access_NetworkDrives_14, Security_Access_NetworkDrives_15, Security_Access_NetworkDrives_16, Security_Access_NetworkDrives_17, Security_Access_NetworkDrives_18, Security_Access_NetworkDrives_19, Security_Access_NetworkDrives_20, Security_Access_NetworkDrives_21, Security_Access_NetworkDrives_22, Security_Access_NetworkDrives_23, Security_Access_NetworkDrives_24, Security_Access_NetworkDrives_25, Security_Access_NetworkDrives_26, Security_Access_NetworkDrives_27, Security_Access_NetworkDrives_28, Security_Access_NetworkDrives_29, Security_Access_NetworkDrives_30, IT_Equipment_1, IT_Equipment_2, IT_Equipment_3, IT_Equipment_4, IT_Equipment_5, IT_Equipment_6, IT_Equipment_7, IT_Equipment_8, IT_Equipment_9, IT_Software_1, IT_Software_2, IT_Software_3, IT_Software_4, IT_Software_Other, IT_Media_1, IT_Media_2, IT_Media_3, IT_Media_Other, IT_Other_Equipment, Additional_Information")] Change change, int? id)
{
    try
    {
        if (ModelState.IsValid)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("SELECTED COUNTRY :- ").AppendLine();
            foreach (var item in change.SecurityAccessList)
            {
                if (item.IsSelected == true)
                {
                    sb.Append(item.Access_Name + ", ").AppendLine();
                    _entities.Changes.Add(change);
                    _entities.SaveChanges();

                    return RedirectToAction("Change");
                }
            }

        }

    }
    catch (System.Data.Entity.Validation.DbEntityValidationException ex)
    {
         foreach (var e in ex.EntityValidationErrors)
        {
            //check the ErrorMessage property
        }
    }
    return View(change);
}

这是 Razor 代码:

<table border="0" width="1000" cellpadding="5" cellspacing="5">
    @for (int i = 0; i < Model.SecurityAccessList.Count; i++)
    {
        <tr>
            <td width="200">
                @Html.CheckBoxFor(m => Model.SecurityAccessList[i].IsSelected)
                @Model.SecurityAccessList[i].Access_Name
                @Html.HiddenFor(m => Model.SecurityAccessList[i].ID)
                @Html.HiddenFor(m => Model.SecurityAccessList[i].Access_Name)
            </td>
        </tr>
    }

在我的 HTTPGET 中,我正在绑定我的列表,但随后我需要 post 我的列表上的检查值。我不知道该怎么做。我在获取检查列表时也遇到了问题,所以它是用逗号分隔的。我似乎无法在网上找到任何可以帮助我解决这个问题的东西。我似乎无法 post 数据到 Security_Change_Access 字段。

首先,不要将复杂对象作为参数传递给 GET 方法。作为复杂对象或集合的属性将不会绑定(它们将为空),您可能会超过查询字符串限制(使您的应用程序崩溃),然后它会创建难看的 url。只需在方法中初始化一个新的 Change,或者传递一个 ID 并根据 ID.

获取 Change

您的视图代码看起来不错,但我建议您使用与复选框关联的标签,并且 Access_Name 属性 的隐藏输入似乎没有必要

@for (int i = 0; i < Model.SecurityAccessList.Count; i++)
{
  @Html.CheckBoxFor(m => m.SecurityAccessList[i].IsSelected)
  @Html.LabelFor(m => m.SecurityAccessList[i].IsSelected, Model.SecurityAccessList[i].Access_Name)
  @Html.HiddenFor(m => m.SecurityAccessList[i].ID)
}

应该生成 html 名称属性如

<input type=checkbox" name="SecurityAccessList[0].IsSelected" ...>
<input type=checkbox" name="SecurityAccessList[1].IsSelected" ...>

接下来,删除(糟糕的)[Bind] 属性。默认情况下,所有属性都是绑定的,这似乎是你想要做的,但实际上你已经排除了 SecurityAccessList (我认为 - tl;dr )并包含了很多 'properties' 不' 甚至存在于您的模型中 (Security_Access_To_1, Security_Access_To_2, .....)。如果您发现自己需要使用 [Bind(Include="..")],请停止并使用视图模型来 display/edit 您需要的东西。

POST 方法应该会正确地将您的模型与包含该集合的 change.SecurityAccessList 绑定。注意我建议您将参数更改为(例如)model。在这种情况下没问题,但是关于绑定失败的问题很多,因为参数的名称与模型的名称相匹配 属性.

旁注:

您为单选按钮列表中似乎使用的内容创建 SelectListList<bTest> list = new List<bTest>(); 位似乎很奇怪。 select 列表甚至不适合这种用法,而且在任何情况下你甚至都不使用 bTestID 属性。它也可能是

SelectList sl = new SelectList(new List<string>() { "Add Access", "Remove Access", "Change Access" });

产生完全相同的结果,虽然我怀疑你需要的只是 属性 成为 List<string>

接下来的 ActiveDirectory objAD = new ActiveDirectory(); 位,您似乎要插入 'default' 或 null 项目以用于 select 列表也是错误的。同样,您使用的唯一 属性 是 displayName 但在任何情况下都将其删除并使用接受 optionLabel

DropDownListFor() 的重载
@Html.DropDownListFor(m => m.YourProperty, Model.ADList, "-Please select-")

这添加了一个 null 选项 <option value>-Please Select-</option>,它可以与 [Required] 属性结合使用。

最后 if (ModelState.IsValid) 块中的代码毫无意义。您甚至不使用 sb 的值(不确定它的作用是什么),然后每次 IsSelected=true 都尝试将 change 的相同实例添加到数据库中,除了它只添加一次,因为一旦添加,您就会进行重定向。