【问题标题】:Html.RenderPartial call from masterpage来自母版页的 Html.RenderPartial 调用
【发布时间】:2010-09-08 02:34:17
【问题描述】:
这是一个场景:假设我的网站有两个控制器负责显示不同类型的内容 - 页面和文章。我需要将部分视图嵌入到我的母版页中,它将列出按某些条件过滤的页面和文章,并显示在每个页面上。我无法在我的母版页上设置模型(对吗?)。如何使用 Html.RenderPartial 解决此任务?
[编辑]
是的,我可能会为列出文章和页面创建单独的部分视图,但仍然存在我不能也不应该在母版页上设置模型的障碍。我需要以某种方式说“这里是页面”作为我的渲染部分和文章的参数。使用 masterpages 中数据库中的数据进行渲染的整个概念对我来说有点模糊。
【问题讨论】:
标签:
asp.net
asp.net-mvc
master-pages
renderpartial
html-helper
【解决方案1】:
如何创建一个 HtmlHelper 扩展方法,允许您在控制器上的操作上调用部分视图结果。
类似
public static void RenderPartialAction<TController>(this HtmlHelper helper, Func<TController, PartialViewResult> actionToRender)
where TController : Controller, new()
{
var arg = new TController {ControllerContext = helper.ViewContext.Controller.ControllerContext};
actionToRender(arg).ExecuteResult(arg.ControllerContext);
}
然后你可以在你的母版页中使用它
<% Html.RenderPartialAction((HomeController x) => x.RenderPartial()) %>
并在您的控制器中使用适当的方法
public PartialViewResult RenderPartial()
{
return PartialView("~/Path/or/View",_homeService.GetModel())
}
反正那是我的 2 美分
【解决方案4】:
ViewData 模型属性只能用于您在 UI 的主要部分查看/编辑的内容。
视图的其他部分可能需要 ViewData 中存在的一些数据,因此只需将这些数据添加到字典中即可。
我只是像这样将字典中的数据传递给部分数据:ViewData["articles"]。 (或来自 MvcContrib 的 ViewData.Get())。
您还可以查看最近在 MvcContrib 中实现的 SubController 模式。
【解决方案5】:
是的,这是正确的。但让我们看看这个场景:
在与文章相关的视图上,我有 ViewData["article"],在与页面相关的视图上,我有 ViewData["pages"],但我并不是一直都有可用的文章和页面。所以,如果我添加:
Html.RenderPartial("articlesView", ViewData["articles"])
Html.RenderPartial("pagesView", ViewData["pages"])
对于我的母版页,我会在 ViewDataDictionary 不包含文章和页面的每个页面上引发异常。
至少,我是这么看的。
【解决方案6】:
我处理这个问题的方法是使用 BaseViewModel。所有视图都是针对继承自 BaseViewModel 的视图模型进行强类型化的。
BaseViewModel 类包含 MasterPage 所需的所有信息。因此,对于导航,您的 BaseViewModel 可能如下所示:
public class BaseViewModel
{
public BaseViewModel()
{
NavigationItems = RetrieveNavigationItemsFromModel();
}
public List<NavItems> NavigationItems {get; set;}
}
在您的 MasterPage 和 PartialViews 中,您可以将模型转换为 BaseViewModel 并访问 NavigationsItems 属性。
<ul>
<% foreach (NavItem ni in (Model as BaseViewModel).NavigationItems) { %>
<li>
<a href="<%= ni.Url %>" alt="<%= ni.Alt%>"><%= ni.DisplayText %></a>
</li>
<% } %>
</ul>
【解决方案7】:
这是一个很晚的回复,但我在谷歌搜索时进入了这个页面 - 所以其他人很可能也会看到这个问题(和我的回复)。
我解决这个问题的方法是使用一个简单的 jQuery 脚本来加载 PartialView 并执行它的控制器代码。示例如下。
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
$(document).ready(function() {
$("#applicationForm").load("/Home/ApplicationForm");
});
</script>
<div id="applicationForm" />
</asp:Content>
这种方法的最大缺点是客户端必须启用脚本才能使其工作(因此它确实对 SEO 不友好)。如果这是你可以忍受的东西,它会很好地工作。我只在一个内部网站上使用它,我知道每个客户端都启用了 JavaScript,我不必担心谷歌的机器人。