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

3
我正在开发一个ASP.Net MVC网站,但我在使用泛型的C#代码与视图协作时遇到了困难。
我的控制器将模型传递给视图(目前还好)。该模型的类型为IDescribedEnumerable,其中T有一些约束条件,包括T必须继承自接口IDescribedModel。
我可以轻松编写一个视图,接受IDescribedEnumerable,只要T实际上是Country类型,就可以正常工作。
然而,我也想编写一个默认视图,接受IDescribedEnumerable<>,并对其进行渲染。这应该是完全可能的。我不总是需要知道模型的具体类型。通常只知道它是一个IDescribedModel就足够了。
只要我留在C#中,就没有问题。当我不关心具体类型时,我只需声明方法和对象接受。当我关心时,我声明它们接受Country。
但是: (1) 如果我想呈现视图,我必须选择一种类型。我不能只说Inherits="System.Web.Mvc.ViewUserControl>",我必须在<>之间指定一个现有类型。(即使我要继承ViewUserControl,我也必须将其转换为IDescribedEnumerable<>。 (2) 理想情况下,在默认视图中,我会说Model是IDescribedEnumerable,在特定实现中是IDescribedEnumerable。然而,我的控制器需要知道他将呈现到默认视图还是特定视图。不能简单地将一个对象从IDescribedEnumerable转换为IDescribedEnumerable。(我记得在C# 4中是可能的,但我正在使用3.5)
那我该怎么办?我能想到的所有选项都非常次优(我不想删除泛型,只是在各个对象之间进行转换,也不想复制默认视图65次并保持同步,也不想进行反射操作并基于已知类型对象创建对象)
3个回答

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

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

...

Model.Cast<IModel>()

在我的ASP.Net MVC版本中,你不能使用Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>",因为它要求T是一个实际类型的名称。此外,model.Cast()返回的是IEnumerable,而不是我的IDescribedEnumerable。 - Jauco

0

没错,那样做可以使用模型作为对象,并适当地进行转换。这就是ViewPage类采用的方法,使用ViewPage和ViewPage:ViewPage。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接