将信息从模型中拉入局部视图

时间:2012-07-06 17:11:23

标签: asp.net asp.net-mvc-3

我正在开发Web应用程序的设计。该应用程序最初并非由我编码,我正在努力在设计时不修改任何控制器或模型。

目前,应用程序是一个标题,应该显示您当前正在查看的项目的名称以及项目的完成日期。此标头是布局调用的局部视图,也是局部视图。因为标题是一个单独的视图,然后是项目详细信息视图,我很难将这些信息拉出来。

我已经尝试将一个@model引用添加到控制器到Header,但是我收到的错误是我传入了错误的类型(参见下面的错误)。

我还尝试将模型传递到布局视图中调用标题的@Html.Partial调用(也是this)。通常我尝试的一切都会给我带来这个错误:

The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[OST.Pride.Business.Models.Project]', but this dictionary requires a model item of type 'OST.Pride.Web.Models.AdminProjectUserEdit'.

我不能只将标题移动到Project Details视图,因为标题是整个应用程序布局的一部分。我很感激任何人的帮助,我已经坚持了一段时间。

在布局中调用标题

<header id="main-header">
  @Html.Partial("LayoutTemplates/Header")
</header>

标题

<div class="navbar" style="padding-top:15px;">
    <div class="navbar-inner">  
        <div class="container" style="width:auto;">           
            <div class="project-navbar"> 
                 <h3><ul class="nav pull-left">Customer: TEST </ul></h3>
                 <h3><ul class="nav" style="padding-left:40%;">Project: //This is where the project name needs to be//</ul></h3>
                 <h3><ul class="nav pull-right" align="center">Project Completion Date: //Again, I need to pull the completion date here// </ul></h3>

            </div>
        </div>
    </div>  
</div>

控制器方法

public ActionResult Details(int? projectid, int? ProjectID, int? projectuserid) // based on the project id, populates the view with the roles, project users, and the roles for the screen.
        {
            var model = new Models.AdminProjectUserEdit();

            model.Project = storeDB.Projects.Find(ProjectID);
            model.Users = storeDB.Users.ToList();

            model.Surveys = storeDB.Surveys.Include("SurveyType").ToList();
            model.ProjectUsers = storeDB.ProjectUsers.Include("Project").Include("User").Where(x => x.ProjectID == projectid).ToList();
            return View(model);
        }

2 个答案:

答案 0 :(得分:3)

这里有一些考虑因素。由于您将其置于布局中,这意味着应用程序中的每个视图都将显示项目详细信息。但要显示项目详细信息,您必须先拥有项目。要拥有一个项目,您必须拥有项目ID。遵循这个逻辑,这意味着您必须为每个请求提供项目ID。此项目标识可以是请求查询字符串或路由的一部分。出于演示的目的,我假设它是路径数据的一部分。

因此,您可以使用child action在布局中显示项目详细信息,而不是部分视图:

<header id="main-header">
    @Html.Action("Header", "SomeController", new { projectid = ViewContext.RouteData["projectid"] })
</header>

注意我们如何从路由数据传递projectId参数。如果项目标识位于查询字符串,cookie或任何决定保留它的位置,您显然必须调整此代码。这条路线似乎是一个好地方。

因此,我们调用Header控制器的Some子操作操作,该操作将获取项目并将其传递给相应的部分视图:

[ChildAction]
public ActionResult Header(int? projectId)
{
    if (projectId == null)
    {
        return PartialView();
    }
    var project = storeDB.Projects.Find(projectID);
    return PartialView(project);
}

然后在相应的Header.cshtml局部视图中,我们呈现项目细节:

@model Project
@if (Model == null)
{
    // there wasn't any project selected => display some default stuff
    <div>No project to display</div>
}
else
{
    <div class="navbar" style="padding-top:15px;">
        <div class="navbar-inner">  
            <div class="container" style="width:auto;">           
                <div class="project-navbar"> 
                     <h3>
                         <ul class="nav pull-left">
                             Customer: TEST
                         </ul>
                     </h3>
                     <h3>
                         <ul class="nav" style="padding-left:40%;">
                             Project:  
                             @Html.DisplayFor(x => x.Name)
                         </ul>
                     </h3>
                     <h3>
                         <ul class="nav pull-right" align="center">
                             Project Completion Date: 
                             @Html.DisplayFor(x => x.CompletionDate)
                         </ul>
                     </h3>
                </div>
            </div>
        </div>  
    </div>
}

答案 1 :(得分:1)

虽然Darin的答案非常好,而且在不同情况下可能会更好地工作,但我决定接受我的主管的建议并使用ViewBag。使用此方法意味着我不需要将模型传递到标头,这是一个共享视图。

以下是我在代码中实现此方法的方法:

在布局中调用标题

<header id="main-header">
    @Html.Partial("LayoutTemplates/Header")
</header>

标题

<div class="navbar" style="padding-top:15px;">
    <div class="navbar-inner">  
        <div class="container" style="width:auto;" >

        @if (@ViewBag.projectName == null)
        { /**do nothing**/ }
        else
        {

            <div class="project-navbar"> 
                 <h3><ul class="nav pull-left">Customer: TEST </ul></h3>
                 <h3><ul class="nav" style="padding-left:40%;">Project: @ViewBag.projectName</ul></h3>
                 <h3><ul class="nav pull-right" align="center">Project Completion Date: @ViewBag.projectCompletion </ul></h3>

           </div>
        } 
        </div>
    </div>  

控制器方法

    public ActionResult Details(int? projectid, int? ProjectID, int? projectuserid) // based on the project id, populates the view with the roles, project users, and the roles for the screen.
    {
        var model = new Models.AdminProjectUserEdit();

        model.Project = storeDB.Projects.Find(ProjectID);
        model.Users = storeDB.Users.ToList();

        model.Surveys = storeDB.Surveys.Include("SurveyType").ToList();
        model.ProjectUsers = storeDB.ProjectUsers.Include("Project").Include("User").Where(x => x.ProjectID == projectid).ToList();
        ViewBag.projectName = storeDB.Projects.Find(ProjectID).ProjectName;
        ViewBag.projectCompletion = storeDB.Projects.Find(ProjectID).ProjectCompletion;
        return View(model);
    }