7

我无法理解这是否可能。我有一个存储过程和一个视图模型类和一个控制器。我是否可以添加另一个具有不同存储过程的视图模型类来使用一个控制器并将来自两个存储过程的信息显示到一个视图中?

这是我目前的模型:

public class People
{
    public class Jobs
    {
        public int jobID { get; set; }
        public string jobName { get; set; }
    }

    public class Names
    {
        public int userId{get;set}
        public string userName {get; set;}
    }
}
4

1 回答 1

14

是的,这是完全可能的。只需创建一个视图模型,其中包含将由您的存储过程填充的属性,然后将其传递给您的视图:

public class PeopleViewModel
{
    public List<Job> Jobs { get; set; }
    public List<Name> Names { get; set; }
}

然后是动作方法:

public ActionResult Index()
{
    var model = new PeopleViewModel();
    model.Jobs = // ... fetch from database
    model.Names = // ... fetch from database

    return View(model);
}

根据评论更新

正如您所说Jobs并且Names是集合,您显示的模型代码不会解决您的问题。听起来这就是你真正想要的:

public class Job // Notice I've removed the pluralisation
{
    public int jobID { get; set; }
    public string jobName { get; set; }
}

public class Name // Notice I've removed the pluralisation
{
    public int userId { get; set; }
    public string userName { get; set; }
}

现在,您的People课程可以包含以下列表:

public class People
{
    public List<Job> Jobs { get; set; }
    public List<Name> Names { get; set; }
}

现在您可以将其包装在视图模型中:

public class PeopleViewModel
{
    public People People { get; set; }
}

然后,您将从您的操作中填充它:

public ActionResult Index()
{
    var model = new PeopleViewModel();
    model.People = // ... fetch from database

    return View(model);
}

问题是,如果Jobs和不相关,那么首先将它们包装在一个类Names中是没有意义的。People您只需执行以下操作(如上所述):

public class PeopleViewModel
{
    public List<Job> Jobs { get; set; }
    public List<Name> Names { get; set; }
}

将视图模型视为仅表示要在视图中显示的一部分数据的方式,仅此而已。上面的所有代码都是定义您希望在该视图中看到的数据。由于视图模型上的属性是公开的,因此您可以使用当前使用的任何方法将它们填充到控制器的操作中。

第二次更新

我认为向您展示一个完整的示例可能会有所帮助,说明如何将您的观点结合在一起。首先,我将向您展示在视图模型中访问数据的快速而肮脏的方式,然后我将向您展示如何使用DisplayTemplates.

快速而肮脏的方法

所以首先,假设我们有一个动作Index,如下所示:

public ActionResult Index()
{
    var model = new PeopleViewModel();
    model.Jobs = // ... fetch from database
    model.Names = // ... fetch from database

    return View(model);
}

这是Index视图:

@model PeopleViewModel

@foreach (var job in Model.Jobs)
{
    @Html.DisplayFor(m => job.JobId)
    @Html.DisplayFor(m => job.JobName)
}

@foreach (var name in Model.Names)
{
    @Html.DisplayFor(m => name.UserId)
    @Html.DisplayFor(m => name.UserName)
}

请注意视图如何期望一个实例,PeopleViewModel并且它只是循环每个集合中的每个单独项目,打印内容。然而,虽然这对于非常简单的视图来说很好,但是在更复杂的视图和更大的项目中,将逻辑与 HTML 混合成为维护难题。考虑到这一点,我们可以DisplayTemplates改为使用。

第二种方法 - 使用模板

控制器中的操作保持不变。但是,我们需要进行一些其他更改。我们正在努力将Index视图变成这样:

@model PeopleViewModel

@Html.DisplayFor(m => m.Jobs)
@Html.DisplayFor(m => m.Names)

通过以这种方式调用Html.DisplayFor,它将尝试定位DisplayTemplate与它正在传递的数据类型相对应的 a。在这种情况下,帮助器足够聪明,知道我们正在将集合传递给它,因此它将寻找与集合包含的数据类型匹配的模板。这意味着我们需要为类型JobName. 为此,请按照下列步骤操作:

  1. DisplayTemplates在视图的当前文件夹内创建一个文件夹(例如,如果您的视图是Home\Index.cshtml,则创建文件夹Home\DisplayTemplates)。
  2. 在该目录中创建一个名称与您的模型匹配的强类型视图(即,在这种情况下,您将创建两个视图,分别称为Job.cshtmlName.cshtml)。

现在您可以将所有显示逻辑移动到这两个模板中。所以它们看起来像下面这样:

作业.cshtml

@model Job

@Html.DisplayFor(m => m.JobId)
@Html.DisplayFor(m => m.JobName)

名称.cshtml

@model Name

@Html.DisplayFor(m => m.UserId)
@Html.DisplayFor(m => m.UserName)

希望这能把事情弄清楚一点。

于 2013-10-01T00:35:30.590 回答