如何从另一个Controller渲染部分

时间:2009-08-28 19:33:08

标签: asp.net-mvc

如果我有一个显示其索引视图的HomeController,我将如何继续使索引视图嵌入来自另一个控制器的UserControl?

以下是主页/索引视图的内容:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    <%=Resources.Global.HomeTitle %>
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData["Message"]) %></h2>
    <p><%=Resources.Global.HomeIndex %></p>

    <h3>Partial title</h3>
    <% Html.RenderPartial("~/Views/OtherController/SomeAction.ascx"); %>

</asp:Content>

这是OtherController的内容:

public class OtherController : BaseController
{
    private readonly IRepositoryContract<SomeType> repo = new SomeTypeRepository();

    public ActionResult SomeAction()
    {
        IQueryable<SomeType> items = repo.GetAllItems();
        return View("SomeAction", items);
    }
}

这给了我一个NullReferenceException,因为RenderPartial()方法永远不会调用Controller。更改以下行

<% Html.RenderPartial("~/Views/OtherController/SomeAction.ascx"); %>

由此

<% Html.RenderPartial("~/Views/OtherController/SomeAction.ascx",((ViewResult) new OtherController().SomeAction()).ViewData.Model); %>

有效,但它肯定是丑陋的。必须有更好的方法来嵌入来自另一个控制器的部分?

更新::找到解决方案

以下是实施Adrian Grigore解决方案后的代码:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="Microsoft.Web.Mvc"%>

    <asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
        <%=Resources.Global.HomeTitle %>
    </asp:Content>

    <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
        <h2><%= Html.Encode(ViewData["Message"]) %></h2>
        <p><%=Resources.Global.HomeIndex %></p>

        <h3>Partial title</h3>
        <% Html.RenderAction("SomeAction","OtherController"); %>

    </asp:Content>

4 个答案:

答案 0 :(得分:5)

使用ASP.NET MVC Futures库中的Html.RenderAction方法。

答案 1 :(得分:4)

将多个控制器使用的部分放入共享文件夹。

必须通过页面传递模型。在控制器中构造它,而不是在视图中构造它。然后像这样传递:

<% Html.RenderPartial("SomeAction", Model.SomeActionData); %>

请注意,如果Model.SomeActionData为null,则MVC将传递Model而不是Model.SomeActionData。确保您的代码可以容忍。

答案 2 :(得分:2)

如果您将视图放在“共享”目录中,您仍然可以使用“部分”。

如果您有共享视图或控件,此解决方案非常简单且易于维护,希望它也是您的替代选择并且对您有用...

答案 3 :(得分:0)

听起来你应该在一个母版页(也许是嵌套版)中拥有共享的UserControl,这样View就不需要知道除了父控件之外的控制器了。 Stephen Walther有一些很好的策略可以将数据传递给master pages and user controls.

  1. 母版页上的代码隐藏(BAD)
  2. ActionFilter
  3. 直接调用部分
  4. 抽象基本控制器类