如何在ASP.NET MVC4中呈现特定模型的视图?

3

我正在学习ASP.NET MVC4,这是我第一次接触Web开发。

我遇到了一个情况。在我的一个控制器中,我将一个IEnumerable<BaseClass>返回到一个视图中。

public class TestController : Controller
{
    public ActionResult Index()
    {
        return View(Models);
    }

    // this static method is just for demo
    static List<BaseModel> Models()
    {
        ...
    }
}

现在,想象一下,在BaseModels中有6个具体类。

public class ConcreteModel1 : BaseModel { .. }  // Must show view1
public class ConcreteModel2 : BaseModel { .. }  // Must show view2
public class ConcreteModel3 : BaseModel { .. }  // and so on..
public class ConcreteModel4 : BaseModel { .. }
public class ConcreteModel5 : BaseModel { .. }
public class ConcreteModel6 : BaseModel { .. }

当我想要显示数据时,每个ConcreteModel都有自己的View,如下图所示。

enter image description here

我该如何实现这个功能呢?如果表述不清,请告诉我。 谢谢。


所以你需要一个基于模型具体类型的复合UI?换句话说,你需要能够显示不同具体类型的未知数量的模块吗? - Mike Perrenoud
@MichaelPerrenoud 没错,根据不同的具体类型 - Darf Zon
好的,我相信我已经为您提供了一个与您所寻找的一样动态和通用的解决方案。 - Mike Perrenoud
3个回答

5
这里有一个完整的解决方案:

模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MvcApplication1.Models
{
    public abstract class BaseModel
    {
        public string Content { get; set; }
    }

    public class ConcreteModel1 : BaseModel { }
    public class ConcreteModel2 : BaseModel { }
    public class ConcreteModel3 : BaseModel { }
}

Composite View

@model System.Collections.Generic.List<MvcApplication1.Models.BaseModel>
@{
    ViewBag.Title = "CompositeView";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>
    CompositeView</h2>
@foreach (var model in Model)
{
    Html.RenderPartial(string.Format("_{0}", model.GetType().Name), model);
}

具体视图

_ConcreteModel1.cshtml

@model MvcApplication1.Models.ConcreteModel1

<h1>Concrete Model 1</h1>
@Model.Content

_ConcreteModel2.cshtml

@model MvcApplication1.Models.ConcreteModel2

<h1>Concrete Model 2</h1>
@Model.Content

_ConcreteModel3.cshtml

@model MvcApplication1.Models.ConcreteModel3

<h1>Concrete Model 3</h1>
@Model.Content

Controller

public ActionResult CompositeView()
{
    List<BaseModel> model = new List<BaseModel>();
    model.Add(new ConcreteModel1() { Content = "This is model 1." });
    model.Add(new ConcreteModel2() { Content = "This is model 2." });
    model.Add(new ConcreteModel3() { Content = "This is model 3." });

    return View(model);
}

它是否消除了在操作中使用Linq连接的需求? - Smoking monkey

3
你可以为 TestView 创建一个组合视图,然后为每个小视图渲染部分视图。要实现这一点,小视图的模型需要在传递给组合视图的模型中可用。
类似于这样:(TestView.cshtml)
@model ParentViewModel

@Html.RenderPartial("View1", Model.SubModel1)
@Html.RenderPartial("View2", Model.SubModel2)
@Html.RenderPartial("View3", Model.SubModel3)

接下来您将有不同的视图,例如:(View1.cshtml)

@model SubViewModel1

<!-- Whatever -->

1
虽然从理论上讲这是正确的,但如果要使布局像 OP 所述的那样动态,就需要使用反射。OP 似乎 特别寻求一种解决方案,可以将它们从列表中呈现出来,而不考虑知道列表中可能有什么。 - Mike Perrenoud

0

我会创建一个自定义模型,其内容是您的 IEnumerable<BaseModel>,并具有其自己内置的按类型检索特定模型的方法。这样,您可以呈现部分视图,并将正确键入的 ConcreteModel 发送到它们中。也许就像这样:

public class UltraModel
{
    // I recommend using an interface rather than a base class
    // to avoid potentially confusing types
    public IBaseModel Models { get; set; }

    public T getModelByType<T>()
    {
        return (T)Models.Where(x => x is T).FirstOrDefault();
    }
}

然后在您的全局视图中,您可以使用以下方式呈现部分视图:

RenderPartial("ConcreteViewName", Model.getModelByType<ConcreteModel1>());

注意:将上面视为伪代码。它可能需要进行微调才能正常工作。


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