Asp.net mvc 绑定属性包含和排除具有复杂类型嵌套对象的属性

Asp.net mvc 绑定属性包含和排除具有复杂类型嵌套对象的属性,asp.net-mvc,asp.net-mvc-3,model-binding,defaultmodelbinder,Asp.net Mvc,Asp.net Mvc 3,Model Binding,Defaultmodelbinder,好吧,这很奇怪。我无法在ASP.NET MVC上对复杂类型的嵌套对象使用BindAttribute的Include和Exclude属性 以下是我所做的: 型号: public class FooViewModel { public Enquiry Enquiry { get; set; } } public class Enquiry { public int EnquiryId { get; set; } public string Latitude { get;

好吧,这很奇怪。我无法在ASP.NET MVC上对复杂类型的嵌套对象使用
BindAttribute
Include
Exclude
属性

以下是我所做的:

型号:

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" />
}
HTTP发布操作:

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" />
}
查看:

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" />
}
@使用(Html.BeginForm()){
@Html.TextBoxFor(m=>m.Enquiry.inquiryId)
@Html.TextBoxFor(m=>m.Enquiry.Latitude)
}
根本不起作用。仅当我为
查询
类定义
BindAttribute
时,我才能做到这一点,如下所述:


是的,您可以让它像这样工作:

[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);
}
这将只包括绑定中的
inquiryID
,并将
纬度保持为空

尽管如此,使用Bind属性并不是我推荐的。我的建议是使用视图模型。在这些视图模型中,您只包含对该特定视图有意义的属性

因此,只需重新调整视图模型:

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

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

好了。不再需要担心绑定。

我想有更好的方法来实现这一点

基本上,如果视图模型中有多个模型,则post controller的签名将包含相同的模型,而不是视图模型

控制器中的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" />
}
@使用(Html.BeginForm()){
@Html.TextBoxFor(m=>m.inquiryv.inquiryId)
@Html.TextBoxFor(m=>m.inquiryv.Latitude)
@Html.TextBoxFor(m=>m.BarV.BarId)
@Html.TextBoxFor(m=>m.ThisNumber)
}
请记住,此表单仍会将Latitude返回(您设置它的方式),但是,由于它未包含在post操作查询的绑定包含字符串中,因此该操作不会接受结果查询中的新值。我建议将latitude设置为禁用或不作为表单元素,以防止额外的发布数据

在任何其他场景中,都可以很好地使用bind,但出于某种原因,它不喜欢复杂模型的点表示法

作为旁注,我不会直接将bind属性放在类上,因为它可能会导致代码复制等其他问题,并且不会考虑您可能希望使用不同绑定的某些场景


(为了清晰起见,我修改了变量名称。我也知道你的问题已经过时了,但在我自己寻找答案的过程中,这是第一次,所以我在尝试自己的解决方案并来到我发布的解决方案之前,偶然发现了这个问题。我希望它能帮助其他人寻求解决同一问题的方法。)

我认为你最好的选择是按照你引用的另一篇文章中描述的那样做。是的,似乎是这样的:我不能在域模型项目中这样做。我想我应该在mvc项目中定义分部类,并在那里这样做。在这里尝试我的解决方案,谢谢@darin。这似乎是唯一的办法。我还没有深入研究过这个问题,但是我们可以通过创建一个新的自定义模型绑定器来调整
DefaultModelBinder
类,使其能够工作吗?@tugberk,我真的不会走这条路。使用视图模型是解决此类问题的方法。不仅仅是这些问题。您应该始终在ASP.NET MVC应用程序中使用视图模型。对于您的第二个建议,我总是介于两者之间:sHere是让我怀疑第二个选项的原因:我在一个单独的项目中创建我的域模型,以便它可以重用,并且完全与业务逻辑分离。我还为域模型项目中的模型定义了验证逻辑。如果我选择第二个选项,就验证而言,我不再与该类的域模型同步。我需要分别为
queryviewmodel
重新定义验证。这就是为什么我介于两者之间。您对此有何想法?@tugberk,我的想法是在视图模型上定义验证逻辑。此验证逻辑并不总是与域模型上的验证逻辑相同。您在视图模型上定义的验证逻辑仅在给定视图的上下文中有效,而域上的验证逻辑对整个应用程序有效。