Answers:
我刚刚遇到了这个问题,只需执行以下操作即可解决该问题:
@for(int i = 0; i < Model.ToGroups.Length; i++)
{
@Html.HiddenFor(model => Model.ToGroups[i])
}
通过使用for而不是foreach,模型绑定将正确运行,并选择列表中的所有隐藏值。似乎是解决此问题的最简单方法。
@Html.HiddenFor(model => Model.ToGroups[i].RowId)
@Html.EditorFor(model => Model.ToGroups[i].Id)
随后@Html.EditorFor(model => Model.ToGroups[i].Description)
的下一个时间-无论是在for循环。控制器能够将其映射到具有这些字段的模型列表。并且要确保所有内容均未出现在屏幕上,只需将其围在<div style="display: none;"></div>
for
-loop 更改为:for(int i = 0; i < Model.Departments.Count(); i++)
HiddenFor与DisplayFor或EditorFor不同。它不适用于集合,仅适用于单个值。
您可以使用MVC Futures项目中提供的序列化HTML帮助器将对象序列化为“隐藏”字段,或者您必须自己编写代码。更好的解决方案是简单地序列化某种ID,然后在回发时从数据库中重新获取数据。
这有点骇人听闻,但是如果您要使用列表,@Html.EditorFor
或者@Html.DisplayFor
要在列表中使用它,请确保将其发送到发帖请求但不可见,您可以display: none;
将其样式化为使用隐藏它,例如:
<div style="display: none;">@Html.EditorFor(model => model.MyList)</div>
如何使用Newtonsoft将对象反序列化为JSON字符串,然后将其插入到Hidden字段中,例如(Model.DataResponse.Entity.Commission是一个简单的“ CommissionRange”对象的列表,您将在JSON中看到)
@using (Ajax.BeginForm("Settings", "AffiliateProgram", Model.DataResponse, new AjaxOptions { UpdateTargetId = "result" }))
{
string commissionJson = JsonConvert.SerializeObject(Model.DataResponse.Entity.Commission);
@Html.HiddenFor(data => data.DataResponse.Entity.Guid)
@Html.Hidden("DataResponse_Entity_Commission", commissionJson)
[Rest of my form]
}
呈现为:
<input id="DataResponse_Entity_Commission" name="DataResponse_Entity_Commission" type="hidden" value="[{"RangeStart":0,"RangeEnd":0,"CommissionPercent":2.00000},{"RangeStart":1,"RangeEnd":2,"CommissionPercent":3.00000},{"RangeStart":2,"RangeEnd":0,"CommissionPercent":2.00000},{"RangeStart":3,"RangeEnd":2,"CommissionPercent":1.00000},{"RangeStart":15,"RangeEnd":10,"CommissionPercent":5.00000}]">
就我而言,在回发之前,我做了一些JS工作来编辑隐藏字段中的json
然后在控制器中,我再次使用Newtonsoft反序列化:
string jsonCommissionRange = Request.Form["DataResponse_Entity_Commission"];
List<CommissionRange> commissionRange = JsonConvert.DeserializeObject<List<CommissionRange>>(jsonCommissionRange);
Html.HiddenFor
仅针对一个值而设计。在创建隐藏字段之前,您将需要以某种方式序列化列表。
例如,如果您的列表是字符串类型,则可以将列表加入逗号分隔的列表中,然后在发回控制器后将其拆分。
我刚刚发现(经过几个小时的尝试弄清楚为什么模型值没有回到控制器后),隐藏的对象应该跟随EditorFor。
除非我做错其他事情,否则这就是我发现的结果。我不会再犯错了。
在包含另一个类列表的Model上下文中。
这将不起作用:
@{
for (int i = 0; i < Model.Categories.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(modelItem => Model.Categories[i].Id)
@Html.HiddenFor(modelItem => Model.Categories[i].ProductCategoryId)
@Html.HiddenFor(modelItem => Model.Categories[i].CategoryName)
@Html.DisplayFor(modelItem => Model.Categories[i].CategoryName)
</td>
<td>
@Html.HiddenFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
@Html.EditorFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
@Html.ValidationMessageFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
</td>
<td style="text-align: center">
@Html.HiddenFor(modelItem => Model.Categories[i].IsSelected)
@Html.EditorFor(modelItem => Model.Categories[i].IsSelected)
</td>
</tr>
}
}
这将在哪里……
for (int i = 0; i < Model.Categories.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(modelItem => Model.Categories[i].Id)
@Html.HiddenFor(modelItem => Model.Categories[i].ProductCategoryId)
@Html.HiddenFor(modelItem => Model.Categories[i].CategoryName)
@Html.DisplayFor(modelItem => Model.Categories[i].CategoryName)
</td>
<td>
@Html.EditorFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
@Html.HiddenFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
@Html.ValidationMessageFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
</td>
<td style="text-align: center">
@Html.EditorFor(modelItem => Model.Categories[i].IsSelected)
@Html.HiddenFor(modelItem => Model.Categories[i].IsSelected)
</td>
</tr>
}
另一种选择是:
<input type="hidden" value=@(string.Join(",", Model.MyList)) />
也许是晚了,但是我为集合中的隐藏字段创建了扩展方法(使用简单的数据类型项):
所以这里是:
/// <summary>
/// Returns an HTML hidden input element for each item in the object's property (collection) that is represented by the specified expression.
/// </summary>
public static IHtmlString HiddenForCollection<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression) where TProperty : ICollection
{
var model = html.ViewData.Model;
var property = model != null
? expression.Compile().Invoke(model)
: default(TProperty);
var result = new StringBuilder();
if (property != null && property.Count > 0)
{
for(int i = 0; i < property.Count; i++)
{
var modelExp = expression.Parameters.First();
var propertyExp = expression.Body;
var itemExp = Expression.ArrayIndex(propertyExp, Expression.Constant(i));
var itemExpression = Expression.Lambda<Func<TModel, object>>(itemExp, modelExp);
result.AppendLine(html.HiddenFor(itemExpression).ToString());
}
}
return new MvcHtmlString(result.ToString());
}
用法很简单:
@Html.HiddenForCollection(m => m.MyList)
<input />
s的期望输出是多少?