【问题标题】:In ASP.NET MVC, How do I make a partial view available to all controllers?在 ASP.NET MVC 中,如何使部分视图可用于所有控制器?
【发布时间】:2026-02-12 21:25:01
【问题描述】:

在 ASP.NET MVC 中,如何使部分视图可用于所有控制器?我想创建整个网站通用的导航,但是当我将 Html.Action 放入我的母版页时,它仅适用于与 1 个控制器关联的视图。

现在,我有一个 控制器操作,定义如下:

    // GET: GetCategoriesPartial
    [ChildActionOnly]
    public ActionResult GetCategoriesPartial()
    {
        var category = CategoriesDataContext.GetCategories();
        return PartialView(category);
    }

我已经像这样创建了我的局部视图

<%@ Import Namespace="wopr.Models" %>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

<ul>
<%
    foreach (var cat in Model as IEnumerable<Category>) {
        %>
        <li><a href="/categories/Details/<%=cat.catID%>"><%=cat.catName%></a></li>
        <%
    }

%>
</ul>

我的母版页如下所示:

<%@ Import Namespace="wopr.Models" %>
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <link type="text/css" rel="Stylesheet" href="/Content/Site.css" />
</head>
<body>
    <div class="wrap-all">
    <div style="text-align:right;">
        <a href="/">Home</a> | 
        <a href="/games/">Games</a> | 
        <a href="/games/Index2/1">Games <em>(paginated)</em></a> | 
        <a href="/categories/">Categories</a> | 
        <a href="/upload/">Upload</a>
    </div>
        <asp:ContentPlaceHolder ID="MainContent" runat="server">

        </asp:ContentPlaceHolder>


        <!--This errors on any non-CategoryController page.-->
            <%= Html.Action("GetCategoriesPartial")%>
        <!---->

    </div>
</body>
</html>

只要我正在查看由 CategoriesController 处理的内容,此代码就可以工作。如果我转到由不同控制器处理的任何视图,我会得到异常:

System.Web.HttpException:在控制器“wopr.Controllers.GamesController”上找不到公共操作方法“GetCategoriesPartial”。

如何使该部分视图可供所有站点的控制器使用?

感谢您的帮助。 鹌鹑

【问题讨论】:

  • 放入共享文件夹?
  • 顺便说一句,如果您想在整个站点共享菜单,您应该考虑将其直接放入母版页,而不是使用 RenderAction 包含它
  • 我确实把它放在了母版页中。这就是为什么我需要让所有控制器都可以使用子操作。
  • 我的意思是菜单是静态内容还是根据登录的用户动态变化的东西?

标签: asp.net-mvc partial


【解决方案1】:

放入views\shared文件夹

但是查看您的错误消息,似乎正在发生其他事情。您不能使用&lt;%=Html.Action%&gt; 来呈现视图。你应该使用&lt;%=Html.RenderPartial("ViewName")%&gt;

【讨论】:

  • 原谅我的菜鸟方式 :-) 那会怎样?我认为不应该在视图中执行任何逻辑。还是可以将部分视图的操作定义放在那里?
  • 您所包含的标记并不真正符合逻辑。用户控件本质上只是一个紧凑的视图。
  • Renderpartial 不需要控制器/动作。正如 Pharabus 所说,它在当前控制器文件夹中查找,然后在视图的共享文件夹中查找。您可以在局部视图中将第二个参数作为模型传递(可选地作为视图数据通过控制器和母版页传递)
  • 我使用了 haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx 推荐的方式。
  • @James:我不明白你想说什么..?
【解决方案2】:

使用 MVC2,您现在可以直接在视图中呈现动作。如果不是从同一个控制器呈现,您将需要指定该操作所在的控制器。如果您以这种方式包含它,您的局部视图可以位于控制器的视图文件夹中(而不是共享)。请注意,它不会从当前操作中获取 ViewData - 只有您正在调用的操作设置的视图数据。

<% Html.RenderAction( "GetCategoriesPartial", "Category" ) %>

<%= Html.Action( "GetCategoriesPartial", "Category" ) %>

【讨论】:

  • 我真的应该继续我的生活..(阅读:移至 MVC2:P)。那会让我得到公认的答案!
  • @ropstah - 我知道你的意思 - 我现在要回去清理 MVC1 应用程序中的很多垃圾,当我这样做时看起来不错,但现在 MVC2 有更多强大的构造看起来像是由一个 5 岁的孩子编写的。公平地说(对平台),其中大部分也反映了我在最初学习它时缺乏知识。 “写这些东西的白痴是谁,哎呀,是我……”
  • 几年前我遇到过它,但一个月前我“身体上”又遇到了一次:VB 中缺少 lambda 构造! :)
【解决方案3】:

添加到 ropstah 的响应中,asp.net-mvc 中的约定是控制器首先查看与自身同名(减去控制器位)的文件夹,然后在共享文件夹下查看查看是否找不到。

【讨论】:

  • 我确实是在输入这个确切的响应,你打败了我! +1
最近更新 更多