查看模型绑定:当绑定的类是抽象的时,有没有办法访问具体实现的属性?

时间:2015-03-02 22:00:18

标签: c# asp.net-mvc razor

我试图在ASP.NET MVC视图的绑定模型中访问抽象对象的具体实现,但我不知道如何绑定属于该属性的属性。具体实施。

public abstract class BasePageVO
{
    public string DisplayText { get; set; }
    public BaseFoo FooItem { get; set; }
}

public class ConcretePageVO : BasePageVO
{
    // some properties

    // in a concrete page, the concrete implementation of BaseFoo is known at compile time.
}

public abstract class BaseFoo
{
    public string FooText { get; set; }
}

public class ConcreteFoo : BaseFoo
{
    public string ConcreteProperty { get; set; }
}

踢球者,以及为什么我采用了这种不寻常的类结构,共享部分也需要了解FooItem,但只知道它的抽象属性。下面简要介绍了结构:

DisplayFoo.cshtml:

@model ConcretePageVO

@using (Html.BeginForm("Submit", "Foo", FormMethod.Post)
{
    @Html.Partial("DisplayFooShared", @Model)
    @Html.EditorFor(x => x.FooItem.ConcreteProperty) @* This fails *@
}

DisplayFooShared.cshtml:

@model BasePageVO

<div>
    @Html.DisplayFor(x => x.DisplayText)
    @Html.EditorFor(x => x.FooItem.FooText)
    @* More properties... *@
</div>

有没有办法向Razor表明BaseFoo对象是预期的具体类型,并且仍然可以从我在共享局部视图中执行模型绑定的方式中获益?我认为我正在为BaseFoo创建自己的自定义模型绑定,就像在Darin's answer here中一样,但ASP.NET抛出了一个编译错误,Razor不知道如何处理属性名称,因为它没有定义。

有没有办法完成对这些特定于实现的属性的绑定,并且仍然受益于ASP.NET MVC提供的强类型?我是否在使用自定义绑定的正确轨道上,但只是拙劣的实现?提前感谢任何建议。

编辑:我将@Html.EditorFor(x => x.FooItem.ConcreteProperty)替换为@Html.EditorFor(x => (x.FooItem as ConcreteFoo).ConcreteProperty),这会导致绑定成功。不过还有更好的办法吗?

2 个答案:

答案 0 :(得分:2)

    public abstract class BaseFoo
    {
        public virtual string FooText { get; set; }
    }

    public class ConcreteFoo : BaseFoo
    {
        public override string FooText { get; set; }
    }

答案 1 :(得分:1)

您正在做的事情违反了面向对象编程的原则。你已经有了一个基类,并且你试图像派生类一样对待它,而这只是一个巨大的红旗。如果您需要派生类,那么您应该在模型中有一个派生类。

否则你唯一的选择是施放,这是一个巨大的代码气味,如果对象实际上不是你认为的衍生对象,则可能存在缺陷。

很可能,您真正的问题是您尝试使用某种域模型作为您的视图模型。您应该将视图模型自定义为该视图所需的模型。然后,您应该将您的域模型映射到您的视图模型,并执行此时所需的任何转换。