2009-08-28 10 views
9

Jeśli mam kontrolkę HomeController wyświetlającą jej widok indeksu, w jaki sposób postępowałbym, aby widok indeksu osadzał kontrolkę UserControl z innego kontrolera?Jak renderować części z innego kontrolera?

Oto spojrzenie na treści Home/Index Widok:

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

Oto treść OtherController:

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

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

To daje mi NullReferenceException ponieważ kontroler nigdy nie jest wywoływana przez Metoda RenderPartial(). Zmiana następującą linię

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

przez tego

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

prac, ale na pewno jest brzydki jak cholera. Musi istnieć lepszy sposób na osadzanie części z innego kontrolera?

Aktualizacja :: Rozwiązanie znaleziono

Oto kod po wdrożeniu Adrian Grigore „s rozwiązanie: partials

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

Odpowiedz

5

Użyj metody Html.RenderAction z biblioteki ASP.NET MVC Futures.

+0

To działa świetnie! Dziękuję Panu. Zmieniłem <% Html.RenderPartial ("~/Views/OtherController/SomeAction.ascx"); %> linia <% Html.RenderAction ("SomeAction", "OtherController"); %> i działa cudownie, wywołując OtherController i wyświetlając poprawne dane. –

4

Put używane przez więcej niż jednego sterownika do folderu udostępnionego.

Model musi zostać przekazany przez stronę. Zbuduj go w kontrolerze, a nie w widoku. Następnie przekazać go tak:

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

Zauważ, że jeśli Model.SomeActionData jest zerowy, a następnie model MVC minie zamiast Model.SomeActionData. Upewnij się, że twój kod może to tolerować.

+0

To znaczy, że będę musiał powielać (lub dziedziczyć) logika budowy modelu w każdym kontrolerze, który osadza wspólną część? Rozumiem, że mogłem po prostu przekazać ViewModel zawierający informacje używane przez tę wspólną część do widoku Home/Index, ale to oznacza, że ​​musiałbym skonstruować/dodać te dane do każdego innego ViewModel View przy użyciu tego częściowego ... Byłoby dla mnie bardziej sensowne, gdyby istniał sposób renderowania częściowych bezpośrednio z innego kontrolera, w którym zaimplementowano odpowiedni model/ViewModel. –

+0

Nie, nie powinieneś nigdy duplikować kodu. Czasami jednak trzeba ją modularyzować. Propozycja Adriana działa dobrze, jeśli nie masz nic przeciwko korzystaniu z kontraktów Futures; sugestia, którą wykonałem, działa, jeśli wolałbyś tego uniknąć. –

0

Wygląda na to, że powinieneś mieć udostępnioną kontrolkę UserControl na stronie wzorcowej (być może zagnieżdżonej), aby widok nie musiał wiedzieć o kontrolerach innych niż nadrzędne. Stephen Walther ma kilka dobrych strategii przekazywania danych do master pages and user controls.

  1. kodu źródłowego na stronie głównej (zły)
  2. ActionFilter
  3. Wywołanie częściowe bezpośrednio
  4. Klasy abstrakcyjne podstawowy kontroler
2

Nadal można użyć opcji "Częściowa", jeśli umieścisz swój widok w katalogu "Udostępnione".

To rozwiązanie jest bardzo proste i utrzymaniu w przypadku, jeśli mają wspólne poglądy lub kontroli, mając nadzieję, że jest również alternatywą i przydatne dla Ciebie ...

Powiązane problemy