asp.net – 将通用模型的子类传递给剃刀视图

前端之家收集整理的这篇文章主要介绍了asp.net – 将通用模型的子类传递给剃刀视图前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
大图:

我发现看起来像是剃刀的限制,我有麻烦想出一个很好的方法.

玩家们:

假设我有一个这样的模型:

public abstract class BaseFooModel<T>
    where T : BaseBarType
{
    public abstract string Title { get; } // ACCESSED BY VIEW
    public abstract Table<T> BuildTable();

    protected Table<T> _Table;
    public Table<T> Table // ACCESSED BY VIEW
    {
        get
        {
            if (_Table == null)
            {
                _Table = BuildTable();
            }
            return _Table;
        }
    }
}

还有一个这样的子类:

public class MyFooModel : BaseFooModel<MyBarType>
{
    // ...
}

public class MyBarType : BaseBarType
{
    // ...
}

我想要能够将MyFooModel传递到如下定义的剃刀视图中:

// FooView.cshtml
@model BaseFooModel<BaseBarType>

但是,这不行.我收到一个运行时错误,说FooView期望BaseFooModel< BaseBarType>但得到MyFooModel.回想一下,来自BaseFooModel&MyBarType>的inits中的MyFooModel而MyBarType继承自BaseBarType.

我试过了

我在非剃刀的土地上试了一下,看看是否也是这样.我不得不在视图中使用模板参数来使其工作.这是非剃刀视图:

public class FooView<T>
    where T : BaseBarType
{
    BaseFooModel<T> Model;
    public FooView(BaseFooModel<T> model)
    {
        Model = model;
    }
}

有了这个结构,下面的工作:

new FooView<MyBarType>(new MyFooModel());

我的问题:

如何用剃须刀做这个?如何传递类似我正在做的FooView?
我不能,但有什么办法吗?我可以以某种方式实现相同的架构吗?

让我知道如果我能提供更多的信息.我正在使用.NET 4和MVC 3.

编辑:
现在,我只是为BaseFooModel< BaseBarType>的每个子类添加一个剃刀视图.我不是很高兴,因为我不想每次添加新的模型时都要创建一个新的视图.

另一个选择是利用这样一个事实,我能够在没有剃刀的普通c#类中得到这个工作.我可以让我的剃须刀视图@继承c#视图,然后调用一些渲染方法.我不喜欢这个选项,因为我不喜欢有两种渲染HTML的方式.

任何其他想法?当我用Foo和Bar提供类名时,我很难理解问题的上下文,但是由于它有点敏感,我无法提供太多的信息.我对此道歉.

我到目前为止,使用本杰明的答案:

public interface IFooModel<out T> 
    where T : BaseBarModel
{
    string Title { get; }
    Table<T> Table { get; } // this causes an error:
                            // Invalid variance: The type parameter 'T' must be 
                            // invariantly valid on IFooModel<T>.Table. 
                            // 'T' is covariant.
}

public abstract class BaseFooModel<T> : IFooModel<T>
    where T : BaseBarModel
{
    // ...
}

最后工作:

public interface IFooModel<out T> 
    where T : BaseBarModel
{
    string Title { get; }
    BaseModule Table { get; } // Table<T> inherits from BaseModule
                              // And I only need methods from BaseModule
                              // in my view. 
}

public abstract class BaseFooModel<T> : IFooModel<T>
    where T : BaseBarModel
{
    // ...
}

解决方法

您需要在类层次结构中引入一个具有 covariant通用类型参数的接口:
public interface IFooModel<out T> where T : BaseBarType
{
}

并从上述界面派生您的BaseFooModel.

public abstract class BaseFooModel<T> : IFooModel<T> where T : BaseBarType
{
}

在你的控制器中:

[HttpGet]
public ActionResult Index()
{
    return View(new MyFooModel());
}

最后,将视图的模型参数更新为:

@model IFooModel<BaseBarType>

猜你在找的asp.Net相关文章