具有复杂类型嵌套对象的bind属性include和exclude属性

时间:2012-01-17 09:52:45

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

好的,这很奇怪。我无法在ASP.NET MVC上使用BindAttribute的{​​{1}}和Include属性以及复杂类型的嵌套对象。

这是我做的:

这是我的模特:

Exculude

HTTP Post动作:

public class FooViewModel {

    public Enquiry Enquiry { get; set; }
}

public class Enquiry {

    public int EnquiryId { get; set; }
    public string Latitude { get; set; }
}

查看:

[ActionName("Foo"), HttpPost]
public ActionResult Foo_post(
    [Bind(Include = "Enquiry.EnquiryId")]
    FooViewModel foo) {

    return View(foo);
}

根本不起作用。如果我为此@using (Html.BeginForm()) { @Html.TextBoxFor(m => m.Enquiry.EnquiryId) @Html.TextBoxFor(m => m.Enquiry.Latitude) <input type="submit" value="push" /> } 类定义了BindAttribute,我是否可以完成这项工作:

How do I use the [Bind(Include="")] attribute on complex nested objects?

2 个答案:

答案 0 :(得分:15)

是的,你可以让它像那样工作:

[Bind(Include = "EnquiryId")]
public class Enquiry 
{
    public int EnquiryId { get; set; }
    public string Latitude { get; set; }
}

和你的行动:

[ActionName("Foo"), HttpPost]
public ActionResult Foo_post(FooViewModel foo) 
{
    return View(foo);
}

这将仅包含绑定中的EnquiryId并保留Latitude null。

这就是说,使用Bind属性不是我推荐你的东西。我的建议是使用视图模型。在这些视图模型中,您只包含对此特定视图有意义的属性。

所以,只需重新阅读你的视图模型:

public class FooViewModel 
{
    public EnquiryViewModel Enquiry { get; set; }
}

public class EnquiryViewModel 
{
    public int EnquiryId { get; set; }
}

你去吧。不再需要担心绑定。

答案 1 :(得分:1)

恕我直言,有更好的方法可以做到这一点。

基本上,如果视图模型中有多个模型,则后控制器的签名将包含相同的模型,而不是视图模型。

public class FooViewModel {
    public Bar BarV { get; set; }
    public Enquiry EnquiryV { get; set; }
    public int ThisNumber { get; set; }
}

public class Bar {
    public int BarId { get; set; }
}

public class Enquiry {
    public int EnquiryId { get; set; }
    public string Latitude { get; set; }
}

控制器中的post动作看起来像这样。

[ActionName("Foo"), HttpPost]
public ActionResult Foo_post(
    [Bind(Include = "EnquiryId")]
    Enquiry EnquiryV,
    [Bind(Include = "BarId"])]
    Bar BarV,
    int ThisNumber
{
    return View(new FooViewModel { Bar = BarV, Enquiry = EnquiryV, ThisNumber = ThisNumber });
}

所有视图仍然如此

@using (Html.BeginForm()) {

    @Html.TextBoxFor(m => m.EnquiryV.EnquiryId)
    @Html.TextBoxFor(m => m.EnquiryV.Latitude)
    @Html.TextBoxFor(m => m.BarV.BarId)
    @Html.TextBoxFor(m => m.ThisNumber)

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

请注意,此表单仍会发布Latitude(您设置的方式),但由于它未包含在发布操作的查询的Bind Include字符串中,因此该操作不会接受新值在结果调查中。我建议禁用纬度或不使用表单元素来阻止其他发布数据。

在任何其他情况下,你可以使用bind很好,但由于某种原因,它不喜欢复杂模型的点符号。

作为旁注,我不会直接在类上放置bind属性,因为它可能会导致代码复制等其他问题,并且不会考虑您可能希望有不同的某些情况结合。

(为了清楚起见,我修改了变量名。我也知道你的问题已经过时了,但是在我自己寻找答案时,这是我在尝试自己的解决方案之前遇到的第一个问题,然后找到我发布的问题。我希望它可以帮助寻求解决同一问题的其他人。)