从多个控制器的动作输出中撰写页面

时间:2012-07-25 08:20:19

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

这是一个建筑哲学问题:)

想要创建非常简单的模块化基于MVC的“CMS”的图像。事实上,你唯一想做的就是你可以用这样的东西指定(例如XML)每个页面的结构(pseudolang):

Use layout: Subpage.cshtml
For section "Header" (placeholder in layout) render controller "Header", action "SubpageHeader"
For section "LeftCol" render controller "Menu" action "MainMenu"
For section "Content" render controller "Articles" action "List"
etc.

那么,优雅和推荐的方法是什么?我现在可以想到两种方式:

选项1:

定义自己的路由,它将捕获所需的URL并为此请求创建自己的MyMvcHandler。在这个处理程序中,处理不会实例化控制器(没有一个“主”),而是会读取“页面结构配置”(上面的示例),实例化所有必需的控制器..但我不确定,该怎么做这一点 - 如何收集行动结果并将其置于布局中?

选项2: 让默认的MvcHandler生效,并且总是调用一些带有默认动作的“MasterController”,它只会返回View(layoutPage);在布局页面中,实现“页面部分”(内容的占位符)作为我自己的帮助方法,类似于Html.RenderAction - 仅定制以查看“页面结构配置”并呈现正确的控制器+操作。但是这样一来,MasterController对我来说似乎毫无用处,有什么方法可以摆脱他吗?

你能想到更好的方法吗?你能看到这些方法的一些基本上升和下降吗?你能指点我一些关于这个主题的好资源吗? (我找不到)。

非常感谢MVC忍者;)

3 个答案:

答案 0 :(得分:0)

由于您需要不同的控制器并且焦点类似于CMS,我建议如下:

  1. 有1个控制器处理用户看到的主要URL和布局(如选项2)

  2. 对于每个部分,都有Ajax回调来获取每个部分的HTML(标题/菜单/文章/等)

  3. 是的,这可以打4个电话,但是权衡很好。

    例如:

    1. 每个部分现在都可以拥有独立的缓存标头。 (例如,布局可以缓存数天/周,而不是经过修改)

    2. 每个部分都可以独立刷新,而无需客户端导航或刷新页面。

    3. 由于每个部分都是独立处理的,因此如果需要,SignalR可用于处理实时更新。

    4. 这些部分(假设它们可能还会得到进一步划分)可以跨页面共享。 (例如,文章可以在多个屏幕上适用的情况下重复使用,......并且还有与利益#1相同的缓存优势)

    5. 如果需要,可以在刷新每个内容片段时通过参数进行每个部分的更改。

    6. 如果需要,可以轻松操作每个部分/控制器/操作以传回Json而不是HTML,以便客户端可以增强功能体验。 (假设您没有使用像淘汰赛这样的框架进行客户端MVC)

    7. 希望这有帮助。

答案 1 :(得分:0)

母版页是实现目标的更简单方法。母版页可用于在应用程序的多个页面之间共享公共内容。这是指向Creating Page Layouts with View Master Pages

的ASP.net MVC网页的链接

希望这有帮助。

答案 2 :(得分:0)

这肯定是可能的,因为你提到的方法(它比部分方法更灵活):

Html.RenderAction("AnyAction", "AnyController")

我认为这个概念的最大问题是状态。如果你走这条路,并且“AnyController”需要维护状态,你需要将其形式化。否则:谁会对查询字符串和帖子变量进行授权?如果变量名冲突,你会怎么做?

请注意,ASP.NET classic已经以某种方式通过其回发状态字段“解决”了这个问题。它为所有页面元素分配唯一ID,并将其放在树中。最大的缺点是它很快就会变得臃肿和低效,就像ASP.NET classic一样。

您还可以查看其他CMS中如何解决此问题,例如N2CMS(免责声明:我对任何其他CMS几乎没有经验)。我认为它的实现在某种程度上类似于你的第二种选择。您在CMS中指定哪些块进入哪个区域,然后系统调用所有视图。不同之处在于,对于子视图,视图的内容模型是由系统计算出来的,而不是由特定的控制器计算出来的,尽管您可以通过调用RenderAction而不是RenderView来概念性地改变它(不确定在实践中的可行性)。但在那种情况下,你再次参加州讨论。