2009-08-28 12 views
9

Si tengo un HomeController que muestra su vista de índice, ¿cómo procedo para que la vista de índice incorpore un UserControl de otro controlador?Cómo renderizar parciales de otro Controlador

Aquí está una mirada en el contenido del Home/Índice de Vista:

<%@ 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> 

Aquí está el contenido OtherController:

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

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

Esto me da una NullReferenceException ya que el controlador no está siendo llamado por el Método RenderPartial() Cambio de la siguiente línea

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

por este

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

obras, pero seguro que es feo como el infierno. Tiene que haber una mejor forma de partials embebidos de otro controlador?

actualización :: solución encontrada

Aquí está el código después de implementar Adrian Grigore 's solución: parciales

<%@ 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> 

Respuesta

5

Utilice el método Html.RenderAction de la biblioteca ASP.NET MVC Futures.

+0

¡Eso funciona genial! Gracias Señor. Cambié el <% Html.RenderPartial ("~/Views/OtherController/SomeAction.ascx"); %> línea por <% Html.RenderAction ("SomeAction", "OtherController"); %> y funciona de maravilla, llama al OtherController y muestra los datos correctos. –

4

Poner utilizados por más de un controlador en la carpeta compartida.

El modelo debe pasar por la página. Constrúyalo en el controlador, no en la vista. A continuación, pasar de esta manera:

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

Tenga en cuenta que si Model.SomeActionData es nulo, entonces pasará MVC Modelo en lugar de Model.SomeActionData. Asegúrate de que tu código pueda tolerar eso.

+0

¿Quiere decir que tendría que duplicar (o heredar) del ¿lógica de construcción del modelo en cada controlador que incrustó el parcial compartido? Entiendo que podría simplemente pasar un modelo de vista que contenga la información utilizada por ese parcial compartido a la vista de inicio/índice, pero eso significa que necesitaría construir/agregar estos datos al ViewModel de todas las vistas usando este parcial también ... Tendría más sentido para mí si hubiera una manera de procesar parciales realmente directamente desde otro controlador en el que se implementa el Modelo/Modelo de Vista relacionado. –

+0

No, nunca debe duplicar el código. Sin embargo, a veces es necesario modularizarlo. La sugerencia de Adrian funciona bien si no te importa usar Futures; la sugerencia que hice funciona si prefiere evitarla. –

0

Parece que debería tener el UserControl compartido en una página maestra (quizás anidada) para que la Vista no necesite conocer controladores que no sean sus padres. Stephen Walther tiene algunas buenas estrategias para pasar datos a master pages and user controls.

  1. de código subyacente de la página principal (BAD)
  2. ActionFilter
  3. Llamando al parcial directamente
  4. clases abstractas controlador base
2

Aún podría usar "Parcial" en caso de que ponga su vista en el directorio "Compartido".

Esta solución es muy simple y fácil de mantener en el caso si usted ha compartido puntos de vista o controles, esperando que también es una alternativa y útil para usted ...

Cuestiones relacionadas