C# 表单复选框组未将所有值发送到控制器
当我的表单中有复选框代码并将其提交给控制器时,只发送第一个复选框值,而忽略所有其他复选框值 表单的示例块:C# 表单复选框组未将所有值发送到控制器,c#,asp.net,asp.net-mvc,asp.net-mvc-4,checkbox,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 4,Checkbox,当我的表单中有复选框代码并将其提交给控制器时,只发送第一个复选框值,而忽略所有其他复选框值 表单的示例块: @:<input type="checkbox" name="commPref" value="23" />Home Phone @:<input type="checkbox" name="commPref" value="24" />Cell Phone @:<input type="checkbox" name="commPref" value="Wor
@:<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
多亏了这篇帖子上所有评论的帮助,以下是最终解决我的问题的方法: 控制器:
[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();
}
}
[HttpPost]
公共行动结果表单(表单数据表单数据,IEnumerable commPref)
{
if(ModelState.IsValid)//执行数据库操作
{
//复选框对象循环-commPref字段
//循环遍历表单字段的每个字符串数组元素以生成结果字段值
if(form_data.commPref!=null)
{
//用于生成以逗号分隔的复选框选项列表的代码
//form_data.commPref=string.Join(“,”,commPref);
//将每个复选框选项包装在管道(|)中,以严格定义在表单上显示的选项
表单_data.commPref=“|”;
foreach(commPref中的var项)
{
表单_data.commPref+=项目;
form_data.commPref+=“|”;
}
}
if(form_data.dataID!=0)//编辑记录
{
db.Entry(form_data).State=EntityState.Modified;
db.SaveChanges();
返回RedirectToAction(“Index”,new{msg=2});
}
else//创建记录
{
db.formapp_Data.Add(form_Data);
db.SaveChanges();
返回RedirectToAction(“Index”,new{msg=1});
}
}
else//显示错误
{
var errors=ModelState.Values.SelectMany(v=>v.errors);
返回视图();
}
}
我知道这一定是太晚了,但以防万一其他人发现自己在这里
MVC确实有办法处理复选框组
在视图模型中:
[显示(Name=“接受哪些信用卡:”)]
公共字符串[]EmployeeRoles{get;set;}
在您的页面上:
<input id="EmployeeRoles" name="EmployeeRoles" type="checkbox" value="Supervisor"
@(Model.EmployeeRoles != null && Model.EmployeeRoles.Contains("Supervisor") ? "checked=true" : string.Empty)/>
<span>Supervisor</span><br />
<input id="EmployeeRoles" name="EmployeeRoles" type="checkbox" value="Auditor"
@(Model.EmployeeRoles != null && Model.EmployeeRoles.Contains("Auditor") ? "checked=true" : string.Empty)/>
<span>Auditor</span><br />
<input id="EmployeeRoles" name="EmployeeRoles" type="checkbox" value="Administrator"
@(Model.EmployeeRoles != null && Model.EmployeeRoles.Contains("Administrator") ? "checked=true" : string.Empty) />
<span>Administrator</span>
主管
审计员
管理员
我非常努力地用razor创建这些控件,但没有骰子。它保持
创建你们都提到过的隐藏字段。对于您的复选框组
您不需要那个隐藏字段,只需要我在上面添加的代码。您可以创建一个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} <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);
}
public static HtmlString CheckboxGroup(此HtmlHelper HtmlHelper,表达式属性选择器,类型EnumType)
{
var groupName=GetPropertyName(propertySelector);
var modelValues=modelmetada.FromLambdaExpression(propertySelector,htmlHelper.ViewData).Model;//propertySelector.Compile().Invoke(htmlHelper.ViewData.Model);
StringBuilder literal=新的StringBuilder();
foreach(Enum.GetValues(EnumType)中的var值)
{
var svalue=value.ToString();
var builder=新标记生成器(“输入”);
builder.GenerateId(groupName);
builder.Attributes.Add(“键入”、“复选框”);
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(“选中”,空);
}
literal.Append(String.Format(“{1}{0}”、svalue.Replace(“”、“”)、builder.ToString(TagRenderMode.Normal));
}
return(HtmlString)htmlhelp.Raw(literal.ToString());
}
私有静态字符串GetPropertyName(表达式propertySelector)
{
var body=propertySelector.body.ToString();
var firstIndex=body.IndexOf('.')+1;
返回body.Substring(firstIndex);
}
在您的页面上,这样使用它:
@CheckboxGroup(m=>m.EmployeeRoles,typeof(Enums.EmployeeRoles))
我使用枚举,但您可以使用任何类型的集合属性的类型是什么
commPref
?(它必须是IEnumerable
)将属性更改为public IEnumerable commPref{get;set;}
(并删除[StringLength]
属性。您将发回一个值数组,因此该属性必须是控制器操作的输入参数所在的数组。尝试将其设置为string[]commPref
尝试这两种建议后,我在这两种情况下都会遇到此错误:类型“string[]”必须是不可为空的值类型,才能将其用作泛型类型或方法“System.Data.Entity.ModelConfiguration.Configuration.StructuralTypeConfiguration.Property(System.Linq.Expressions.Expression)”中的参数“T”“
它向我指出了这个上下文片段:modelBuilder.Entity().Property(e=>e.commPref)
错误表明commPref
是数据模型中的一个属性。在这种情况下,您的操作完全是错误的。您需要一个具有属性IEnumerable commPref
的视图模型,因为它需要是一个数组来绑定到您创建的控件。然后,您可以使用String.Split()映射到视图模型和从视图模型映射
和String.Join()
假设数据模型中的commPref
类型为String
(并且您需要一个(比如)逗号分隔的列表)此声明也适用于ActionResult:[HttpPost]公共ActionResult表单(form\u data form\u data,String[]commPref)
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} <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);
}