如何将通用对象传递给Aspx页面

时间:2009-12-14 09:22:37

标签: c# asp.net-mvc generics asp.net

我正在开发一个ASP.Net MVC网站,我一直在使用泛型来获取我的C#代码,以便与我的观点保持良好关系。

我有一个将模型传递给视图的控制器(到目前为止一直很好)。模型的类型为IDescribedEnumerable<T>,对T有一些约束,其中T是从接口(IDescribedModel)继承的约束。

我可以轻松编写一个接受IDescribedEnumerable<Country>的视图,只要T实际上是Country类型,该视图就会有效。

但是,我还想编写一个默认视图,该视图接受IDescribedEnumerable <<whatever>>并将呈现它。这应该是完全可能的。我并不总是需要知道模型的具体类型。通常只知道它是IDescribedModel就足够了。

只要我留在C#就没问题了。当我不关心特定类型时,我只是将方法和对象声明为接受<T>。当我照顾时,我声明他们接受Country

但:
(1)如果我想渲染一个视图我必须选择一个类型。我不能只说Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>"我必须在<>之间指定现有类型。 (即使我要继承ViewUserControl,我也必须将其投放到IDescribedEnumerable<<something>>。 (2)理想情况下,我会说默认视图中的模型为IDescribedEnumerable<IDescribedModel>,具体实现中为IDescribedEnumerable<Country>。但是,我的Controller需要知道他是否要渲染到默认视图或特定视图。无法简单地将IDescribedEnumerable<Country>的对象强制转换为IDescribedEnumerable<IDescribedModel>。 (IIRC可以在C#4中使用,但我使用的是3.5)

那我该怎么办?我能想到的所有选项都是非常不理想的(我不期待删除泛型,只是将对象转换为周围,也不是复制粘贴默认视图65次并保持副本同步,也不会反射出色并创建一个对象基于已知的Type对象)

3 个答案:

答案 0 :(得分:0)

在等待一些C#天才来回答我所有问题时,我已经实现了IEnumerable也使用的技巧:

我在IDescribedEnumerable接口中添加了一个方法public IDescribedEnumerable<IDescribedModel> AsIDescribedModels(),并创建了一个新类GenericDescribedEnumerable<T> : IDescribedEnumerable<IDescribedModel>。在我的DescribedEnumerable<T>类中,我创建了一个GenericDescribedEnumerable并返回它。在GenericDescribedEnumerable中,我返回this

完整代码:

public interface IDescribedModel<T> : IDescribedModel{
    T original {
        get;
    }
}

public interface IDescribedEnumerable {
    IDescribedEnumerable<IViewModel> AsIViewModels();
}

public interface IDescribedEnumerable<T> : IDescribedEnumerable
    where T : IDescribedModel{
    IEnumerable<T> GetViewModels();
}

public class DescribedEnumerable<T> : IDescribedEnumerable<IDescribedModel<T>>{

    public DescribedEnumerable(IEnumerable<T> enumerable) {}

    public IDescribedEnumerable<IViewModel> AsIViewModels() {
        return new GenericDescribedEnumerable<T>(/*allProperties*/);
    }

    public IEnumerable<T> GetViewModels() {
        foreach ( T obj in _enumerable ) {
            var vm = new DescribedModel<T>( obj);
            yield return vm;
        }
    }
}

public class GenericDescribedEnumerable<T> : IDescribedEnumerable<IViewModel>{
    //pass in the constructor everything you need, or create in the 
            //constructor of DescribedEnumerable<T>
    public GenericDescribedEnumerable(/*allProperties*/) {
    }

    public IEnumerable<IViewModel> GetViewModels() {
        foreach ( T obj in _enumerable ) {
            var vm = new PlatoViewModel<T>( obj );
            yield return vm;
        }
    }

    public IDescribedEnumerable<IViewModel> AsIViewModels() {
        return this;
    }
}

答案 1 :(得分:0)

是的,这将起作用或使用模型作为对象,并适当地投射它。这是ViewPage类使用的方法,使用ViewPage和ViewPage:ViewPage。

答案 2 :(得分:0)

Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>"

...

Model.Cast<IModel>()