简体   繁体   中英

How to render the view of specific models in ASP.NET MVC4?

I'm learning ASP.NET MVC4, this in my first experience in Web development.

I'm dealing with a situation. In one of my controllers, I'm returning a IEnumerable<BaseClass> to a View.

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

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

Imagine now, that we have 6 concrete class in BaseModels.

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 { .. }

When I want to display the data, each ConcrenteModel has its own View . As it's shown in the below image.

在此输入图像描述

How can I accomplish this? If I wasn't very clear, please let me know Thanks.

Here is a complete solution:

Models

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

Concrete Views

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

You can have a composite view for the TestView and then render partial views for each of the smaller views. To accomplish this the models for the smaller views will need to be available from the model passed to the composite view.

Something like this: (TestView.cshtml)

@model ParentViewModel

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

You then have separate views, like: (View1.cshtml)

@model SubViewModel1

<!-- Whatever -->

I would actually create a custom model whose contents were your IEnumerable<BaseModel> that had its own built in methods for retrieving a specific model by type. That way you can render partial views and send into them the specific ConcreteModel typed properly. Maybe something like:

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

Then in your global view you can render partials with:

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

Note: Treat the above as psuedo-code. It will likely need to be tweaked to work just right.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM