我的主视图模型有一个 ChildViewModel 的集合。在视图中,我循环遍历集合并调用 EditorFor(),如下所示:
@for (int i = 0; i < Model.Children.Count; i++)
{
@Html.EditorFor(m => m.Child[i]);
}
编辑器模板如下所示:
@model ChildModel
@using (Html.BeginForm("EditChild", "MyController"))
{
@Html.HiddenFor(m => m.ChildId)
@Html.TextBoxFor(m => m.ChildName)
}
这将生成标记,其中每个子项都位于单独的表单中,并且每个此类表单将有一个名称如 Child[0].ChildName 的输入控件。我为每个子项使用单独的表单,因为子项将在每一行上显示一个,然后用户可以编辑并提交一行。
我的表单操作方法是:
[HttpPost]
public ActionResult EditChild(ChildViewModel form) { }
问题是,当调用它时,模型的所有属性都将为空,因为模型绑定器不知道前缀。在某些情况下,我们可以使用 BindAttribute 告诉模型绑定器有关前缀的信息,但在这种情况下,前缀不是常量:它将是 Child[0]、Child[1] 等。
总之,我们希望为集合的每一行重复相同的表单,然后允许用户 POST 单个表单。在这种情况下,Web 如何处理 id、名称、前缀和模型绑定?
我和你有同样的问题,我的解决方案是这样的,希望对你有帮助。
在 EditorTemplate 或部分视图中添加隐藏输入
<input type="hidden" name="__prefix" value="@ViewData.TemplateInfo.HtmlFieldPrefix" />
定义自定义模型绑定器并重写 BindModel 方法
public class CustomModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var prefixValue = bindingContext.ValueProvider.GetValue("__prefix");
if (prefixValue != null)
{
var prefix = (String)prefixValue.ConvertTo(typeof(String));
if (!String.IsNullOrEmpty(prefix) && !bindingContext.ModelName.StartsWith(prefix))
{
if (String.IsNullOrEmpty(bindingContext.ModelName))
{
bindingContext.ModelName = prefix;
}
else
{
bindingContext.ModelName = prefix + "." + bindingContext.ModelName;
// fall back
if (bindingContext.FallbackToEmptyPrefix &&
!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
{
bindingContext.ModelName = prefix;
}
}
}
}
return base.BindModel(controllerContext, bindingContext);
}
}
模型绑定器将修剪前缀并使默认模型绑定起作用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)