asp.net-mvc 如何在 ASP.NET MVC 的一个视图中使用多个模型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5829315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 01:09:53  来源:igfitidea点击:

How to use multiple models in one view for ASP.NET MVC?

asp.net-mvcentity-framework

提问by Monochrome

I've read similar questions on SO but can't seem to figure out this issue, which is specific to DBContext objects (I think). Here's some dummy code to illustrate.

我已经阅读了关于 SO 的类似问题,但似乎无法弄清楚这个问题,这是特定于 DBContext 对象的(我认为)。这里有一些虚拟代码来说明。

I have the following code in my Index() action:

我的 Index() 操作中有以下代码:

    public ActionResult Index()
    {
        AnimalDBContext db = new AnimalDBContext();

        return View(db.Dogs);
    }

I have the following code for my models:

我的模型有以下代码:

    public class Dog
    {
        public int ID { get; set; }
        public string name { get; set; }
        public string breed { get; set; }
    }

    public class AnimalDBContext : DbContext
    {
        public DbSet<Dog> Dogs { get; set; }
    }

In my view I have the following:

在我看来,我有以下几点:

@model IEnumerable<AnimalProject.Models.Dog>
    @foreach (var d in Model)
    {
    <h3>@d.name</h3>
    <h2>@d.breed</h2>
    }

Everything works great, the view will loop through every dog in my database. However, I have another set of DBContext data from another table that I want in the same view. I want to be able to enumerate each item in the database for that table as well.

一切正常,视图将遍历我数据库中的每条狗。但是,我在同一视图中还有来自另一个表的另一组 DBContext 数据。我也希望能够为该表枚举数据库中的每个项目。

This is what I want, if you catch my drift:

这就是我想要的,如果你明白我的意思:

@model IEnumerable<AnimalProject.Models.Dog>
@model IEnumerable<AnimalProject.Models.Cat>
    @foreach (var d in Dog)
    {
    <h3>@d.name</h3>
    <h2>@d.breed</h2>
    }
    @foreach (var c in Cat)
    {
    <h3>@c.name</h3>
    <h2>@c.breed</h2>
    }

I have tried grouping the classes together and using a partial view, but apparently you can't have a different model in a partial view, because I always get the error message:

我尝试将类组合在一起并使用局部视图,但显然在局部视图中不能有不同的模型,因为我总是收到错误消息:

"The model item passed into the dictionary is of type 'System.Data.Entity.DbSet1[AnimalProject.Models.Dog]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[AnimalProject.Models.Cat]'."

“传递到字典中的模型项的类型是‘System.Data.Entity.DbSet 1[AnimalProject.Models.Dog]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[AnimalProject.Models.Cat]’。”

So, how can I use multiple models in my view that both get the data I want from separate tables in the database?

那么,如何在我的视图中使用多个模型来从数据库中的单独表中获取我想要的数据?

回答by Ladislav Mrnka

What about creating custom view model class:

创建自定义视图模型类怎么样:

public AnimalModel
{
    public IEnumerable<Dog> Dogs { get; set; }
    public IEnumerable<Cat> Cats { get; set; }
} 

Fill this model in Index and pass it to the view which will expect AnimalModelinstead of enumerables.

在 Index 中填充此模型并将其传递给将期望AnimalModel而不是可枚举的视图。

Edit:

编辑:

Filling the model:

填充模型:

public ActionResult Index()
{
    using (var db = new AnimalDBContext())
    {
        var model = new AnimalModel 
        {
            Dogs = db.Dogs.ToList(),
            Cats = db.Cats.ToList()
        };

        return View(model);
    }
}

View (I have never used Razor so I hope this is correct):

查看(我从未使用过 Razor 所以我希望这是正确的):

@model AnimalProject.Models.AnimalModel
@foreach (var d in Model.Dogs)
{
  <h3>@d.name</h3>
  <h2>@d.breed</h2>
}
@foreach (var c in Model.Cats)
{
  <h3>@c.name</h3>
  <h2>@c.breed</h2>
}

回答by Thanasis Ioannidis

A model is just an object like any other object in C# (or VB)

模型只是一个对象,就像 C#(或 VB)中的任何其他对象一样

So you can pass any object you want to the view, even complex ones. If you need to present a lot of things, then create a view model (a model just for the view's needs) which contains all the things you want to present and pass this one to the view. Then, from within the view, you access the model's individual properties on the different parts of the view, to present them. An example of this approach is the Animal Model Ladislav Mrnka talked about. You put in there the dogs and cats enumerables and then pass it to the view. You tell the view that your model now is this AnimalModel type etc etc...

所以你可以将任何你想要的对象传递给视图,甚至是复杂的对象。如果你需要展示很多东西,那么创建一个视图模型(一个只满足视图需要的模型),它包含你想要展示的所有东西,并将这个传递给视图。然后,在视图中,您可以在视图的不同部分访问模型的各个属性,以显示它们。这种方法的一个例子是 Ladislav Mrnka 谈到的动物模型。你把狗和猫的可枚举放在那里,然后将它传递给视图。你告诉视图你的模型现在是这个 AnimalModel 类型等等......

So, since a model is just an object, and if you are lazy enough to not want to create another custom view model, then you can pass your whole dbcontext as a model to the view like this.

因此,由于模型只是一个对象,如果您懒得创建另一个自定义视图模型,那么您可以像这样将整个 dbcontext 作为模型传递给视图。

Controller

控制器

public ActionResult Index()
{
   return View(new AnimalDBContext()); // We pass a new instance of the dbcontext to the view
}

View

看法

@model AnimalProject.AnimalDBContext // we declare that our model is of type AnimalDBContext 
@foreach (var d in Model.Dogs) // We reference the dbcontext's sets directly
{
  <h3>@d.name</h3>
  <h2>@d.breed</h2>
}
@foreach (var c in Model.Cats) // We reference the dbcontext's sets directly
{
  <h3>@c.name</h3>
  <h2>@c.breed</h2>
}

Now you have declared to your view that your "Model" object will be an AnimalDBContext So you can access all the AnimalDBContext's properties, sets etc directly from within your view. It may not be the best abstraction for the data access, but look how simple your controller has become! :) You just throw the whole world into the view and let it decide which parts to pick and present... Of course this is for simple scenarios. If you wanted more complex stuff you would have to fall back to custom view models eventually.

现在您已经向您的视图声明您的“模型”对象将是一个 AnimalDBContext 因此您可以直接从您的视图中访问所有 AnimalDBContext 的属性、集合等。它可能不是数据访问的最佳抽象,但看看您的控制器变得多么简单!:) 您只需将整个世界放入视图中,让它决定选择和呈现哪些部分……当然,这是针对简单场景的。如果您想要更复杂的东西,您最终将不得不退回到自定义视图模型。

回答by vhallac

The only solution to this problem I've found so far is to chuck both models in the ViewBag, and then render partial views for parts that use only one model. Of course, it only works if the partial views are separable - as is in your case. This allows strongly typed partial views compared to accessing the contents of the ViewBagdirectly.

到目前为止,我发现的这个问题的唯一解决方案是将两个模型都放在 中ViewBag,然后为仅使用一个模型的部件渲染部分视图。当然,它只有在部分视图是可分离的情况下才有效——就像你的情况一样。与直接访问 的内容相比,这允许强类型的部分视图ViewBag

The solution is similar to Ufuk's answer here. First put data in ViewBagfrom controller:

解决方案类似于 Ufuk 在此处的回答。首先ViewBag从控制器放入数据:

ViewBag.Dogs = db.Dogs;
ViewBag.Cats = db.Cats;

Then render the partial View from the view:

然后从视图渲染局部视图:

@Html.Partial("_ListDogs", ViewBag.Dogs)
@Html.Partial("_ListCats", ViewBag.Cats)

And each partial view would be along the lines of the following (example is _ListDogs.cshtml):

每个局部视图都将遵循以下内容(示例为_ListDogs.cshtml):

@model IEnumerable<AnimalProject.Models.Dog>
@foreach (var d in Model)
{
    <h3>@d.name</h3>
    <h2>@d.breed</h2>
}