繁体   English   中英

复杂的对象和模型绑定器ASP.NET MVC

[英]Complex object and model binder ASP.NET MVC

我有一个带有Foo类的模型对象结构,该类包含一个带有字符串值的Bar

public class Foo
{
    public Bar Bar;
}

public class Bar
{
    public string Value { get; set; }
}

还有一个使用这种结构的视图模型

public class HomeModel
{
    public Foo Foo;
}

然后,我认为有一个表单在Razor中看起来像这样。

<body>
    <div>
        @using (Html.BeginForm("Save", "Home", FormMethod.Post))
        {
            <fieldset>
                @Html.TextBoxFor(m => m.Foo.Bar.Value)
                <input type="submit" value="Send"/>
            </fieldset>
        }

    </div>
</body>

在html中。

<form action="/Home/Save" method="post">
    <fieldset>
        <input id="Foo_Bar_Value" name="Foo.Bar.Value" type="text" value="Test">
        <input type="submit" value="Send">
    </fieldset>
</form>

最后,控制器来处理这样的帖子

[HttpPost]
public ActionResult Save(Foo foo)
{
    // Magic happends here
    return RedirectToAction("Index");
}

我的问题是,一旦Foo中的Bar命中了Save控制器动作(创建FooBar字段为null ,它就为null

我认为MVC中的模型绑定程序将能够创建FooBar对象并设置Value属性,只要它看起来像上面一样即可。 我想念什么?

我也知道我的视图模型有点复杂,可能会更简单,但是对于我想做的事情,如果我可以使用更深的对象结构,那将对我有很大帮助。 上面的示例使用ASP.NET 5。

首先, DefaultModelBinder不会绑定到字段,因此您需要使用属性

public class HomeModel
{
  public Foo Foo { get; set; }
}

其次,助手正在基于HomeModel生成控件,但是您将其发回到Foo 将POST方法更改为

[HttpPost]
public ActionResult Save(HomeModel model)

或使用BindAttribute指定Prefix (实际上是从发布的值中Bar.Value前缀的值-出于绑定的目的, Foo.Bar.Value变为Bar.Value )。

[HttpPost]
public ActionResult Save([Bind(Prefix="Foo")]Foo model)

还要注意,您不应使用与属性之一相同的名称来命名方法参数,否则绑定将失败并且模型将为null。

我刚刚发现了发生这种情况的另一个原因,那就是如果您的媒体资源名为Settings 考虑以下视图模型:

public class SomeVM
{
    public SomeSettings DSettings { get; set; } // named this way it will work

    public SomeSettings Settings { get; set; } // property named 'Settings' won't bind!

    public bool ResetToDefault { get; set; }
}

在代码中,如果绑定到Settings属性,它将无法绑定(不仅在发布时,甚至在生成表单时)。 如果将Settings重命名为Settings DSettings (等),则突然可以再次使用。

我遇到了同样的问题,按照@Stephen Muecke的步骤进行操作后,我意识到问题是由我的输入被禁用(我在准备好文档的JQuery上禁用它们)引起的,您可以在此处看到: 如何在以下位置提交禁用的输入ASP.NET MVC? 最后,我使用了只读属性而不是禁用属性,并且所有值都成功发送到了控制器。

我遇到了同样的问题,但是一旦我为外键创建了一个“隐藏字段”,它就可以正常工作了……

表格范例:

@using (Html.BeginForm("save", "meter", FormMethod.Post))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    @Html.HiddenFor(model => Model.Entity.Id)
    @Html.HiddenFor(model => Model.Entity.DifferentialMeter.MeterId)
    @Html.HiddenFor(model => Model.Entity.LinearMeter.MeterId)
    @Html.HiddenFor(model => Model.Entity.GatheringMeter.MeterId)

    ... all your awesome controls go here ...
}

动作示例:

// POST: /Meter/Save
[HttpPost]
public ActionResult Save(Meter entity)
{
    ... world-saving & amazing logic goes here ...
}

漂亮图片:
在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM