【问题标题】:Form Checkbox Group not sending all values to Controller表单复选框组未将所有值发送到控制器
【发布时间】:2016-05-29 23:12:09
【问题描述】:

当我的表单中有复选框代码并将其提交给控制器时,仅发送第一个复选框值,而忽略所有其他选中的值。

表单块示例:

@:<input type="checkbox" name="commPref" value="23" />Home Phone
@:<input type="checkbox" name="commPref" value="24" />Cell Phone
@:<input type="checkbox" name="commPref" value="Work" />Work Phone
@:<input type="checkbox" name="commPref" value="26" />Email
@:<input type="checkbox" name="commPref" value="27" />Mail

提交给Controller后:

  • 如果检查了手机和电子邮件,“Model.commPref”=“24”-NOT-“24,26”
  • 如果选中了工作电话、电子邮件和邮件,则 "Model.commPref" = "Work" -NOT- "Work,26,27"

我对此完全感到困惑。表单复选框周围是否需要额外的代码才能将值组合在一起?在 ColdFusion 中,发回的表单值是检查值的完整字符串。表单控件的“名称”都相同(commPref),因此这应该是该字段的结果值。

编辑:这是模型描述:

[StringLength(255)]
public string commPref { get; set; }

【问题讨论】:

  • commPref 的属性类型是什么? (必须是IEnumerable&lt;int&gt;
  • 将属性更改为public IEnumerable&lt;string&gt; commPref { get; set; }(并删除[StringLength] 属性。您回发了一个值数组,因此该属性需要是一个数组
  • 控制器动作的输入参数是什么。试着让它string[] commPref
  • 在尝试了这两种建议后,我在两种情况下都得到了这个错误:The type 'string[]' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Data.Entity.ModelConfiguration.Configuration.StructuralTypeConfiguration&lt;TStructuralType&gt;.Property&lt;T&gt;(System.Linq.Expressions.Expression&lt;System.Func&lt;TStructuralType,T&gt;&gt;)' 它指向这个上下文 sn-p:modelBuilder.Entity&lt;form_Data&gt;() .Property(e =&gt; e.commPref);
  • 错误提示commPref是数据模型中的一个属性。在这种情况下,你做这一切都是错的。您需要一个具有属性IEnumerable&lt;string&gt; commPref 的视图模型,因为它需要是一个数组才能绑定到您创建的控件。然后您可以使用String.Split()String.Join() 在视图模型之间进行映射,假设数据模型中的commPref 是typeof string(并且您想要一个(比如说)逗号分隔列表)

标签: c# asp.net asp.net-mvc asp.net-mvc-4 checkbox


【解决方案1】:

我知道这肯定太晚了,但以防万一其他人发现自己在这里..

MVC 确实有办法处理复选框组。

在您的视图模型中:

[Display(Name = "接受哪些信用卡:")]

public string[] EmployeeRoles{ get;放; }

在您的页面上:

            <input id="EmployeeRoles" name="EmployeeRoles" type="checkbox" value="Supervisor" 
            @(Model.EmployeeRoles != null && Model.EmployeeRoles.Contains("Supervisor") ? "checked=true" : string.Empty)/>
            &nbsp;<span>Supervisor</span><br />

            <input id="EmployeeRoles" name="EmployeeRoles" type="checkbox" value="Auditor" 
            @(Model.EmployeeRoles != null && Model.EmployeeRoles.Contains("Auditor") ? "checked=true" : string.Empty)/>
            &nbsp;<span>Auditor</span><br />

            <input id="EmployeeRoles" name="EmployeeRoles" type="checkbox" value="Administrator" 
            @(Model.EmployeeRoles != null && Model.EmployeeRoles.Contains("Administrator") ? "checked=true" : string.Empty) />
            &nbsp;<span>Administrator</span>

我非常努力地用剃刀而不是骰子来创建这些控件。它使 创建你们都提到的隐藏字段。对于您的复选框组 你不需要那个隐藏字段,只需要我上面添加的代码。您可以创建一个 html 帮助程序来为您创建此代码。

    public static HtmlString CheckboxGroup<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> propertySelector, Type EnumType)
    {
        var groupName = GetPropertyName(propertySelector);
        var modelValues = ModelMetadata.FromLambdaExpression(propertySelector, htmlHelper.ViewData).Model;//propertySelector.Compile().Invoke(htmlHelper.ViewData.Model);

        StringBuilder literal = new StringBuilder();  

        foreach (var value in Enum.GetValues(EnumType))
        {
            var svalue = value.ToString();
            var builder = new TagBuilder("input");
            builder.GenerateId(groupName);
            builder.Attributes.Add("type", "checkbox");
            builder.Attributes.Add("name", groupName);
            builder.Attributes.Add("value", svalue);
            var contextValues = HttpContext.Current.Request.Form.GetValues(groupName);
            if ((contextValues != null && contextValues.Contains(svalue)) || (modelValues != null && modelValues.ToString().Contains(svalue)))
            {
                builder.Attributes.Add("checked", null);
            }

            literal.Append(String.Format("</br>{1}&nbsp;<span>{0}</span>", svalue.Replace('_', ' '),builder.ToString(TagRenderMode.Normal)));
        }

        return (HtmlString)htmlHelper.Raw(literal.ToString()); 
    }

    private static string GetPropertyName<T, TProperty>(Expression<Func<T, TProperty>> propertySelector)
    {
        var body = propertySelector.Body.ToString();
        var firstIndex = body.IndexOf('.') + 1;
        return body.Substring(firstIndex);
    }

在您的页面上像这样使用它: @Html.CheckboxGroup(m => m.EmployeeRoles, typeof(Enums.EmployeeRoles))

我使用枚举,但你可以使用任何类型的集合

【讨论】:

    【解决方案2】:

    感谢这篇文章所有评论者的帮助,这最终解决了我的问题:

    控制器:

        [HttpPost]
        public ActionResult form(form_Data form_data, IEnumerable<string> commPref)
        {
            if (ModelState.IsValid) // Perform DB Actions
            {
                // Checkbox Object Loop - commPref field
                // Loop through each string array element of form field to build resulting field value
                if (form_data.commPref != null)
                {
                    //Code to make comma-delimited list of Checkbox choices
                    //form_data.commPref = string.Join(",", commPref);
                    //Wraps each Checkbox choice in pipes (|) to strictly define choice for display on form
                    form_data.commPref = "|";
                    foreach (var item in commPref)
                    {
                        form_data.commPref += item;
                        form_data.commPref += "|";
                    }
                }
    
                if (form_data.dataID != 0) // Edit Record
                {
                    db.Entry(form_data).State = EntityState.Modified;
                    db.SaveChanges();
                    return RedirectToAction("Index", new { msg = 2 });
                }
                else // Create Record
                {
                    db.formapp_Data.Add(form_data);
                    db.SaveChanges();
                    return RedirectToAction("Index", new { msg = 1 });
                }
    
            }
            else // Show Errors
            {
                var errors = ModelState.Values.SelectMany(v => v.Errors);
                return View();
            }
        }
    

    【讨论】:

    • 此声明也适用于 ActionResult:[HttpPost] public ActionResult form(form_Data form_data, string[] commPref)
    猜你喜欢
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多