我正在尝试为一组属性动态创建隐藏字段,但是当我提交表单时,我收到500服务器错误。我确认了以下内容:
这就是我所拥有的:
查看
@model PaneViewModel
using (Ajax.BeginForm("AddItem", "Action", new AjaxOptions
{
UpdateTargetId = "tool-wrapper",
HttpMethod = "POST",
}))
{
// Some standard input fields here (these are working properly).
[...]
// Here's what's broken:
@foreach (var property in Model.NewItem.GetType().GetProperties().Where(<criteria here>))
{
@Html.HiddenFor(m => m.NewItem.GetType().GetProperty(property.Name), column.GetValue(Model.NewItem, null))
}
<button type="submit">Add</button>
}
ItemViewModel
public class ItemViewModel
{
public int SomeField { get; set; }
public int AnotherField { get; set; }
}
PaneViewModel
public class PaneViewModel
{
public ItemViewModel NewItem { get; set; }
}
控制器
[HttpPost]
public ActionResult AddItem([Bind(Prefix = "NewItem")] ItemViewModel model)
{
// Stuff here.
}
值得注意的是,以下内容会在生成的HTML中生成具有正确名称和值的隐藏字段,但隐藏字段的值不会发布到控制器操作:
@foreach (var property in Model.NewItem.GetType().GetProperties().Where(<criteria here>))
{
@Html.Hidden(property.Name, column.GetValue(Model.NewItem, null))
}
所以似乎问题在于m => m.NewItem.GetType().GetProperty(property.Name)
组件
答案 0 :(得分:1)
Html.HiddenFor()
期望表达式(Expression<Func<TModel,
TProperty>>
)作为第一个参数,但.GetProperty()
会返回
typeof PropertyInfo
但是,如果你想这样做,你可以创建一个html助手,为所有标有[HiddenInput]
属性的属性生成隐藏的输入(或者修改这个例子以传递一些条件,过滤所需的属性)
public static MvcHtmlString HiddenForModel<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
{
StringBuilder html = new StringBuilder();
ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
var properties = metaData.Properties.Where(p => p.TemplateHint == "HiddenInput");
foreach(var property in properties)
{
html.Append(helper.Hidden(property.PropertyName));
}
return MvcHtmlString.Create(html.ToString());
}
请注意,这也会生成可能不必要的id
和data-val-*
属性,因此您可以使用
foreach(var property in properties)
{
TagBuilder input = new TagBuilder("input");
input.MergeAttribute("type", "hidden");
input.MergeAttribute("name", property.PropertyName);
input.MergeAttribute("value", string.Format("{0}", property.Model));
html.Append(input.ToString());
}