asp.net-mvc - 如何处理集合的每一行重复相同形式的 MVC 模型绑定(bind)前缀?

标签 asp.net-mvc asp.net-mvc-3 model-binding

我的主视图模型有一个 ChildViewModel 集合。在 View 中,我循环遍历集合并调用 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) { }

问题是,当调用它时,模型的所有属性都将为空,因为模型绑定(bind)器不知道前缀。在某些情况下,我们可以使用 BindAttribute 告诉模型绑定(bind)器有关前缀的信息,但在这种情况下,前缀不是常量:它将是 Child[0]、Child[1] 等。

总之,我们希望为集合的每一行重复相同的表单,然后允许用户 POST 单个表单。在这种情况下,Web 如何处理 id、名称、前缀和模型绑定(bind)?

最佳答案

我和你有同样的问题,我的解决方案是这样的,希望对你有帮助。

在 EditorTemplate 或部分 View 中添加隐藏输入

<input type="hidden" name="__prefix" value="@ViewData.TemplateInfo.HtmlFieldPrefix" />

定义自定义模型绑定(bind)器并重写 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);
    }
}

模型绑定(bind)器将修剪前缀并使默认模型绑定(bind)起作用。

关于asp.net-mvc - 如何处理集合的每一行重复相同形式的 MVC 模型绑定(bind)前缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14978241/

相关文章:

c# - 无法填充 Kendo Scheduler

c# - NancyFx 将模型绑定(bind)到动态类型?

jquery - 在 mvc 中,使用基于表单的模型绑定(bind)与 javascript 序列化时如何获得响应?

asp.net-mvc - ASP.NET MVC RC - 创建一个带有代码的 MVC 用户控件

CSS 图像未在 ASP.NET MVC 中显示

javascript - Ajax 不与 owl-carousel 一起使用

c# - 如何在 Html.Editor 中直接加载 Object additionalViewData 的值?

javascript - 如何使用 ajax 发送对象数组和其他表单数据?

c# - 有没有关于在没有默认 ASP.Net 成员提供程序的情况下创建 MVC3 登录系统的教程?

c# - 在 Web API 2 的自定义绑定(bind)器中使用默认 IModelBinder