MVC模型绑定到嵌套类

8
当我尝试创建一个新的“流(Flow)”类时,控制器中嵌套的类(“行为(Action)”)总是返回为null。
所以我有像这样嵌套的类:
public class Flow
{
    private Action actionField
    private string nameField
    private bool enabledField
    ...
}

public class Action
{
    private ActionSchedule actionScheduleField
    private ActionParameter actionParameterField
    private nameField
}
public class ActionSchedule
...

为“Flow”创建一个单独的创建视图

@model ProjectZeus.Models.Flow
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

   @Html.TextBoxFor(model => model.name, new { @placeholder = "Flow name" })
   @Html.ValidationMessageFor(model => model.name)


   @Html.LabelFor(model => model.enabled)

   @Html.EditorFor(model => model.enabled)
   @Html.ValidationMessageFor(model => model.enabled)

@Html.Partial("FlowAction")
...

然后为每个子类创建部分视图。

@model ProjectZeus.Models.FlowAction

    @Html.TextBoxFor(model => model.name, new { @placeholder = "Action name" })
    ...

我已经尝试创建类的实例并调用视图-出现错误, 我已经尝试在视图本身中创建类的实例-出现错误, 我已经尝试不使用PartialViews:
@Html.TextBoxFor(model => model.action.name, new { @placeholder = "Action name" })

我已经谷歌搜索了很多次,但没有成功,请求帮助!

编辑:

实现一个客户模型绑定器似乎有些过头了。这个页面描述了相同的问题,但是解决方案代码不适用于我,“当前上下文中不存在'helper'的名称”?-http://danielhalldev.wordpress.com/2013/08/23/partial-views-and-nested-mvc-model-binding/

编辑2:

我更改了模型定义以缩短长度 - 该模型实际上是从xsd自动生成的:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class D53ESBFlow
{

    private D53ESBFlowAction actionField;

    [Required]
    private string nameField;

    ...

    private bool enabledField;

    /// <remarks/>
    public D53ESBFlowAction action
    {
        get
        {
            return this.actionField;
        }
        set
        {
            this.actionField = value;
        }
    }
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;

编辑 3(提升):

看起来“binder”正在创建一个属性而不是类对象? whereRu


Action 不是嵌套类,而是 Flow 类中的一个属性。 - Yair Nevet
动作似乎具有nameField属性,而不是name。 此外,Flow具有actionField,而不是Action。 - sander
我已经更改了一些名称/签名,模型类是从XSD自动生成的。这可能会有问题吗? - Jimmy
我的意思是,如果你将视图绑定到Flow模型并且Flow具有名为“actionField”的Action属性,则应该这样调用部分:@Html.Partial(“FlowAction”,Model.actionField),而不是@Html.Partial(“FlowAction”,Model.action),因为Flow没有名为“action”的属性。 - sander
抱歉,问题已更新。实际上我只是使用视图名称调用@Html.Partial而没有传递模型。 - Jimmy
显示剩余5条评论
4个回答

4

你是否忘记了在属性名称上添加 { get; set; } 访问器?


面掌 就是这样了! - FirstVertex

1

我在使用MVC 5,.NET 4.5和Visual Studio 2013时遇到了类似的问题。

以下是解决方法:添加一个构造函数以实例化包含的类,像AntoineLev说的那样将它们改为属性而不是变量,并将该类添加到绑定中:

public class Flow
{
    public Action actionField {get; set; }

    public class Flow()
    {
        actionField = new Action();  // otherwise it shows up as null
    }
}

在你的控制器中,将整个类添加到绑定中:
public ActionResult Create([Bind(Include="action,name,enabled")] Flow flow)
{
   ... 
}

你的里程可能会有所不同。

}


有趣的是,刚刚在自动生成的mvc5控制器中看到了“Bind(Include =”语法。不过这只对第一个嵌套类有效,对吧? - Jimmy
@Jimmy 刚刚测试了嵌套类,令人惊讶的是,它们也被正确映射了。我不得不为嵌套类添加构造函数,并为底层类的属性添加 {get; set;}。更棒的是,它还可以捕获该 T 类的 List<T>。 - TomEberhard
很好的回答,但是需要注意的是:如果你要绑定整个类,那么就不需要[Bind(Include="blah blah blah")]了。它默认会绑定所有内容。 - Kat
Bind属性对于保护方法非常有用。它只接受Flow对象的以下属性 -黑客可以尝试向对象注入额外的字段- 因此从这个角度来看,建议使用该属性。但是在您的情况下,它不应影响绑定。 - Mazen Elkashef

0

最后,我通过请求响应并逐个按名称映射所有属性。

flow.action = new D53ESBFlowAction
    {
        name = Request["action.name"],
        ...

0

我曾经遇到过类似的问题,而Jimmy's Bogard的这篇文章帮助了我。文章在这里

查看生成的HTML代码会发现,在使用部分视图时,HTML代码不包括嵌套类的名称,因此默认情况下无法绑定它。像上面某个答案中给出的绑定语句可以解决这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接