繁体   English   中英

更好的方法来生成全局ViewData?

[英]Better way to generate global ViewData?

我的网站的一部分需要导航下拉列表的全局数据,现在我在属性中执行以下操作:

ViewData["projects"] = new[]
{
    new ProjectNav { Id = 1, Name = "Big project in New York" },
    new ProjectNav { Id = 2, Name = "Small project in New Jersey" },
    new ProjectNav { Id = 3, Name = "Big project in Florida" },
}

然后我标记我的控制器方法,如下所示:

[ProjectNav]
public ActionResult Index() 
{
     // strongly typed view returned here
}

在我看来,我会做这样的事情:

<% foreach (ProjectNav project in (IEnumerable<ProjectNav>)ViewData["projects"]) 
{ %>
// Enumerate here
<% } %>

这是有效的,但无论如何以更强的类型方式执行此操作? 我唯一能想到的是使用ProjectNav作为成员创建一个Dto,但是你为每个控制器方法创建了一个单独的Dto,这绝对不是DRY。 有没有更好的方法来解决这个问题,我只是错过了?

有一个NavigationController,并在每个视图(或母版页)中使用RenderAction或RenderPartial。

在其上创建一个带有Projects属性的基础ViewModel类。

在ActionFilter中创建一个OnResultExecuted方法。 OnResultExecuted方法中访问模型( filterContext.Controller.ViewData.Model )。 检查它是否来自您的基本ViewModel类。 如果是,请将其投射并将项目数据添加到其中。

现在,您在视图模型上有一个强类型的Projects属性,并使用ActionFilter进行设置。

或者,您也可以使用接口而不需要单个基本ViewModel类... if (model is IDisplayProjects) ...

全球导航数据下降,这意味着它是页眉或页脚的一部分吗? 我的方法是更喜欢声明它并将其加载到母版页中,或者更多的代码,放入具有特定功能的每个Controller的构造函数中。

我会将模型放入Session并在用户首次登录时初始化该会话属性。或者如果没有登录,则在实际页面上初始化它。 如果您的全局数据表示每个页面,则将其放在母版页中。

所以在masterpage中这样的东西(其中GetProjects是一个静态函数):

<% if(Session["projects"] == null)
{
   Session["projects"] = DataManager.GetProjects();
}%>

<% foreach (ProjectNav project in (IEnumerable<ProjectNav>)Session["projects"]) 
{ %>
     // Enumerate here
<% } %>

这不是最强类型的方法,但非常简单和有效。 因此,通过这种方式,您无需在控制器级别担心它。

使用子操作是一个更好的解决方案。 所以你首先要定义一个控制器:

public class ProjectsController: Controller
{
    public ActionResult Index()
    {
        var projects = new[]
        {
            new ProjectNav { Id = 1, Name = "Big project in New York" },
            new ProjectNav { Id = 2, Name = "Small project in New Jersey" },
            new ProjectNav { Id = 3, Name = "Big project in Florida" },
        };
        return View(projects);
    }
}

然后有一个强类型的部分将呈现它们( ~/Views/Projects/Index.ascx )并最终在主视图中包含它:

<%= Html.Action("index", "projects") %>

这样您就不需要使用属性来装饰所有控制器操作。 只需使用Html.Action帮助程序包含您需要的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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