为各种模型动态创建隐藏的表单字段(MVC 4)
Dynamically creating hidden form fields for various models (MVC 4)
我试图为一组属性动态创建隐藏字段,但在提交表单时遇到了500服务器错误。我确认了以下内容:
- 我在foreach语句中迭代的属性是正确的
- property.Name是NewItem.GetType()检索到的类型的有效属性名称
这是我的:
查看
@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)
组件
- 这种类型的逻辑不属于视图
Html.HiddenFor()
期望表达式(Expression<Func<TModel, TProperty>>
)作为第一个参数,但.GetProperty()
返回PropertyInfo
类型- 您不应该为属性生成多个隐藏输入而是使用视图模型来只表示您需要进行编辑(它通过向客户,然后将其再次张贴回,保持不变,以及任何人可以使用FireBug或类似工具来更改值也许一点也不明智
但是,如果您确实想这样做,您可以创建一个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-*
属性,这可能是不必要的,因此您可以通过使用来最小化生成的html
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());
}
相关文章:
- 通过单击动态加载的表中同一行的另一个字段来更新一行的字段
- 添加和删除隐藏字段数组中的值,而不提交表单
- 单击鼠标,用MySQL数据填充html表单输入字段
- 带有条件字段的PHP表单
- 防止在输入字段上单击事件
- 高级自定义字段按单选按钮值排序
- 使用JQuery启用输入字段的单选框
- SmartyStreets:使用条件字段调整表单中已验证勾号的位置
- 组合功能以使用 Jquery 在一组单选按钮中显示输入字段和单选按钮
- 使只读字段不可单击
- 使用 JavaScript 进行 HTML 字段表单验证
- JavaScript 在不输入输入字段/表单的情况下传递输入
- JQuery 在动态添加输入字段时单击浏览,而 ajax 不起作用
- 我可以让时间选择器在输入字段中单击时触发吗?
- 将隐藏字段表单值传递给控制器
- 隐藏小视口中的字段,单击按钮再次显示
- 我可以给html文本字段表单中的元素提供相同的名称和id吗
- 在新行上显示输入字段(基于单选)
- 在文本字段(表单)后插入节点
- 动态生成的名称字段的单选按钮组验证