2

我正在设计一个 Web 应用程序。该应用程序最初不是由我编写的,我正在努力在设计时不修改任何控制器或模型。

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

我尝试将控制器的@model 引用添加到 Header,但收到错误,我传递了错误的类型(请参阅下面的错误)。

我还尝试将模型传递给 Layout 视图中的 @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'.

我不能只将标题移动到项目详细信息视图,因为标题是整个应用程序布局的一部分。我会感谢任何人的帮助,我已经坚持了一段时间。

在布局中调用标题

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

2 回答 2

3

这里很少考虑。由于您将其放在布局中,这意味着应用程序中的每个视图都将显示项目详细信息。但要显示项目详细信息,您必须先有一个项目。要拥有一个项目,您必须有一个项目 ID。按照这个逻辑,这反过来意味着您必须在每个请求的任何地方都有项目 ID。此项目 ID 可以是请求查询字符串或路由的一部分。出于本演示的目的,我假设它是路线数据的一部分。

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

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

注意我们是如何projectId从路由数据中传递参数的。如果项目 id 在查询字符串、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>
}
于 2012-07-06T17:19:38.447 回答
1

虽然达林的回答非常好,并且在不同的情况下可能会更好地工作,但我决定接受主管的建议并使用 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);
    }
于 2012-07-06T19:15:55.960 回答