1

使用 MVC 4 Forms,我有一个模型,它总是在一个List<T>属性中包含四个孩子。该视图正确显示模型,其中四个子模型中的每一个都使用 Razor 局部视图渲染。问题是,当我提交/发布时,模型用子列表的空值反序列化。

模型:

public class MyModel
{
    public int SomeValue { get; set; }

    public List<ChildModel> Children { get; set; }

    ...
}

看法:

@model MyProject.Models.MyModel

@using (Html.BeginForm())
{
    @Html.LabelFor(model => model.SomeValue)

    @Html.Partial("ChildPartial", Model.Children[0])
    @Html.Partial("ChildPartial", Model.Children[1])
    @Html.Partial("ChildPartial", Model.Children[2])
    @Html.Partial("ChildPartial", Model.Children[3])

    <input type="submit" value="Save" />
}

控制器:

public class MyController : Controller
{
    public ActionResult Index()
    {
        MyModel model = new MyModel();
        model.Children = new List<ChildModel>();

        model.Children.Add(new ChildModel());
        model.Children.Add(new ChildModel());
        model.Children.Add(new ChildModel());
        model.Children.Add(new ChildModel());

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyModel model)
    {
        //model.Children is null here

        //do stuff
        ...

        return RedirectToAction("Index", "SomeOtherController");
    }
}

每个ChildPartial视图都正确呈现,我正在将值输入到控件中,但它们没有反序列化到List<ChildModel>. 我只能MyModel在 Post 方法中获取要反序列化的根级别属性。

我尝试添加UpdateModel(model);到控制器 Post 方法的开头,但那里没有运气。有任何想法吗?

编辑

ChildModel.cs:

public class ChildModel
{
    public String Name { get; set; }
    public double Ratio { get; set; }
    ...
}

ChildPartial.cshtml:

@model MyProject.Models.ChildModel

<div>
    <div>
        <div>
            <span>@Model.Name</span>
        </div>
        <div>
            @Html.LabelFor(m => m.Ratio)
            @Html.TextBoxFor(m => m.Ratio, new { autocomplete = "off" })
            @Html.ValidationMessageFor(m => m.Ratio)
        </div>
    </div>

    ...
</div>
4

1 回答 1

3

我首先建议您阅读默认模型绑定器期望的特定语法以及绑定到集合时的命名约定:http: //haacked.com/archive/2008/10/23/model-binding-to-a-list .aspx

将输入字段的名称与本博文中解释的名称进行比较后,您将很快理解为什么您的代码不起作用。您根本没有遵循标准命名约定。

为了解决这个问题,我建议您使用编辑器模板。因此,在您的主视图中放置以下内容:

@model MyProject.Models.MyModel

@using (Html.BeginForm())
{
    @Html.LabelFor(model => model.SomeValue)

    @Html.EditorFor(model => model.Children)

    <input type="submit" value="Save" />
}

然后将您的移动ChildPartial.cshtml~/Views/Shared/EditorTemplates/ChildModel.cshtml. 请注意,模板的名称和位置非常重要。确保您已遵循它。并将其放入:

@model MyProject.Models.ChildModel

<div>
    <div>
        <div>
            <span>@Model.Name</span>
        </div>
        <div>
            @Html.LabelFor(m => m.Ratio)
            @Html.TextBoxFor(m => m.Ratio, new { autocomplete = "off" })
            @Html.ValidationMessageFor(m => m.Ratio)
        </div>
    </div>

    ...
</div>

好的,现在运行您的项目,检查生成的 HTML,更具体地说,将输入字段的名称与您的初始版本进行比较,并将它们与我最初在我的答案中链接到的博客文章进行比较,您将了解有关模型绑定的一切到集合在 ASP.NET MVC 中工作。

Name备注:在您的子模板中,您的 ChildModel的属性没有相应的输入字段。因此,如果它在您的控制器中为空,请不要感到惊讶。提交表单时,您根本不会向它发送值。如果您希望发生这种情况,您可以将其作为隐藏字段包含在您的编辑器模板中:

@Html.HiddenFor(m => m.Name)
于 2013-07-24T20:25:48.080 回答