复杂类型嵌套对象的绑定属性包含和排除属性

发布于 2024-12-27 10:22:02 字数 1086 浏览 2 评论 0原文

好吧,这很奇怪。我无法在 ASP.NET MVC 上将 BindAttributeIncludeExclude 属性与复杂类型嵌套对象一起使用。

这是我所做的:

模型:

public class FooViewModel {

    public Enquiry Enquiry { get; set; }
}

public class Enquiry {

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

HTTP POST 操作:

[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" />
}

根本不起作用。只有当我为 Enquiry 类定义 BindAttribute 时,我才能完成这项工作,如下所述:

如何在复杂嵌套对象上使用 [Bind(Include="")] 属性?

Ok, this is weird. I cannot use BindAttribute's Include and Exclude properties with complex type nested objects on ASP.NET MVC.

Here is what I did:

Model:

public class FooViewModel {

    public Enquiry Enquiry { get; set; }
}

public class Enquiry {

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

HTTP POST action:

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

    return View(foo);
}

View:

@using (Html.BeginForm()) {

    @Html.TextBoxFor(m => m.Enquiry.EnquiryId)
    @Html.TextBoxFor(m => m.Enquiry.Latitude)

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

Does not work at all. Can I only make this work if I define the BindAttribute for Enquiry class as it is stated here:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余厌 2025-01-03 10:22:02

是的,您可以使其像这样工作:

[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 保留为空。

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

因此,只需重新调整您的视图模型即可:

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

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

就这样。不再需要担心绑定问题。

Yes, you can make it work like that:

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

and your action:

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

This will include only the EnquiryId in the binding and leave the Latitude null.

This being said, using the Bind attribute is not something that I would recommend you. My recommendation is to use view models. Inside those view models you include only the properties that make sense for this particular view.

So simply readapt your view models:

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

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

There you go. No longer need to worry about binding.

长伴 2025-01-03 10:22:02

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

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

IE

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; }
}

控制器中的后操作将如下所示。

[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" />
}

,但请记住,此表单仍将回发纬度(按照您设置的方式),但是由于它不包含在后操作的查询的绑定包含字符串中,因此该操作将不接受结果查询中的新值。我建议将纬度禁用或不作为表单元素,以防止额外的发布数据。

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

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

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

IMHO there is a better way to do this.

Essentially if you have multiple models in the view model the post controller's signature would contain the same models, as opposed to the view model.

I.E.

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; }
}

And the post action in the controller would look like this.

[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 });
}

All while the view still looks like this

@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" />
}

Keep in mind, this form will still post Latitude back (the way you had it set up), however since it is not included in the Bind Include string for Enquiry on the post action, the action will not accept the new value in the resultant Enquiry. I'd suggest making latitude either disabled or not a form element to prevent additional posting data.

In any other scenario you can use bind just fine, but for some reason it dislikes the dot notation for complex models.

As a side note, I wouldn't put the bind attribute on the class directly as it can cause other issues like code replication, and doesn't account for certain scenarios where you may want to have a different binding.

(I modified the variable names for some clarity. I am also aware your question is rather dated, however in searching for the answer myself this is the first SO I stumbled upon before trying my own solutions and coming to the one I posted. I hope it can help out other people seeking a solution to the same issue.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文