2008-11-10 17 views
11

Gram w ASP.NET MVC i miałem pytanie. A może jest to troska, że ​​robię to źle. Po prostu pracuję nad kiepską stroną, żeby trochę rozciągnąć skrzydła. Przykro mi, że to pytanie wcale nie jest zwięzłe.ASP.Net MVC i RenderPartial w ścieżkach względnych

OK, oto scenariusz. Gdy użytkownik odwiedza stronę główną/indeks, strona powinna wyświetlić listę produktów i listę artykułów. Układ jest taki plik (DAL jest mój warstwa dostępu do danych):

 
Controllers 
    Home 
     Index  

Views 
    Home 
     Index  inherits from ViewPage 
    Product   
     List  inherits from ViewUserControl<IEnumerable<DAL.Product>> 
     Single  inherits from ViewUserControl<DAL.Product> 
    Article 
     List  inherits from ViewUserControl<IEnumerable<DAL.Article>> 
     Single  inherits from ViewUserControl<DAL.Article> 
Controllers.HomeController.Index produces a View whose ViewData contains two entries, a IEnumerable<DAL.Product> and a IEnumerable<DAL.Article>. 

View.Home.Index will use those view entries to call: 
Html.RenderPartial("~/Views/Product/List.ascx", ViewData["ProductList"]) 
and Html.RenderPartial("~/Views/Article/List.ascx", ViewData["ArticleList"]) 

View.Product.List will call 
foreach(Product product in View.Model) 
    Html.RenderPartial("Single", product); 

View.Article.List does something similar to View.Product.List 

Podejście to jednak nie powiedzie. Podejście ma dla mnie sens, ale może ktoś, kto ma większe doświadczenie z platformami MVC, rozpozna lepszy sposób.

Powyższe powoduje błąd w pliku View.Product.List. Połączenie z numerem Html.RenderPartial("Single",...) skarży się, że nie znaleziono "pojedynczego" widoku. Błąd pojawia się:

 
The partial view 'Single' could not be found. The following locations were searched: 
~/Views/Home/Single.aspx 
~/Views/Home/Single.ascx 
~/Views/Shared/Single.aspx 
~/Views/Shared/Single.ascx 

Bo dzwoni RenderAction() ze względu na produkt, spodziewałem runtime szukać „single” widzenia w Wyświetleń \ Produktu. Wygląda jednak na to, że wyszukiwanie jest względne dla kontrolera, który wywołał pierwotny widok (/ Controller/Home invoked/Views/Product) zamiast bieżącego widoku.

Więc jestem w stanie rozwiązać ten problem przez widoków zmieniającym \ Produktu, takie, że:

View.Product.List will call 
foreach(Product product in View.Model) 
    Html.RenderPartial("~/Views/Product/Single.ascx", product);

zamiast

View.Product.List will call 
foreach(Product product in View.Model) 
    Html.RenderPartial("Single", product); 

Ta poprawka działa .. ale nie rozumiem dlaczego ja potrzebowałem podaj pełną ścieżkę widoku. Dla mnie sensowne byłoby interpretowanie względnej nazwy względem ścieżki bieżącego widoku, a nie ścieżki widoku oryginalnego kontrolera. Nie mogę wymyślić żadnego przydatnego przypadku, w którym interpretacja nazwy względem widoku kontrolera zamiast bieżącego widoku jest przydatna (z wyjątkiem typowego przypadku, gdy są one takie same).

Mniej więcej w tym czasie powinienem mieć znak zapytania? Podkreślenie tego jest właściwie pytaniem.

+0

Właśnie natknął to szuka czegoś związanego (zdaję sobie sprawę, jego powyżej 6 miesięcy). Ale wspomniałeś o użyciu RenderAction(), jednak wszystkie twoje przykłady używają RenderPartial(), czy to literówka? Zakładam, że RenderAction (w przeciwieństwie do RenderPartial) powinien działać w tej sytuacji? –

Odpowiedz

4

[edit:

Myślałam, masz 2 przypadki:

  • kontroler Home jest jedyną osobą, która kiedykolwiek odwołuje kontrolę wyrobów/Artykuły użytkownika Lista
  • kontrole użytkownika są dzielone przez kilka kontrolerów:

W pierwszym przypadku kontrolki użytkownika widoku rzeczywiście należą do kontrolera domowego i ma sens umieszczenie ich w kontrolerze domowym folder oller. W drugim przypadku sensowne jest umieszczenie ich w folderze współdzielonym, ponieważ będą one współdzielone przez kontrolery.

W obu przypadkach możesz umieścić je w podfolderze. Podobnie jak widoki/Home/Products, a następnie wypróbować RendarPartial ("Product/Single") i zobaczyć, co się stanie? Nie wiem, czy spróbowałoby to rozwiązać: Home/Product/Single, a następnie Shared/Product/Single, czy też nie. Jeśli działają podfoldery, wydaje się, że pozwalają na logiczną separację Produktu i artykułu, pokazując, że nadal są członkami kontrolera Macierzystego lub Współdzielonego przez wszystkie kontrolery.

]

Sprawdź ten wpis na blogu Steve Sanderson:

http://blog.codeville.net/2008/10/14/partial-requests-in-aspnet-mvc/

Co robisz nie jest źle, ale wydaje się jakby wbrew konwencji View/Nazwy folderów kontrolerów. Powiedział, że ma sens, aby chcieć zdefiniować kontrolki użytkownika, które nie są kontrolowane przez kontroler, a ich zagnieżdżanie wydaje się być prawidłowe. Więc nie wiem!

W każdym razie, łącze opisuje tylko metodę zamiast RenderPartial do renderowania kontroli użycia, definiuje metodę RenderPartialRequest, która renderuje wartość zwracaną (w twoim przypadku kontrolką użytkownika) akcji kontrolera. Możesz więc dodać kontroler produktów i artykułów z listą działań, która zwróci kontrolę użytkownika, a następnie wywołać te dwie akcje z widoku Strona główna/indeks. Wydaje mi się to bardziej intuicyjne, ale tylko opinia.

Wspomniał również o kontrolerach MVC Contrib i jestem pewien, że istnieje ochota na coś takiego, aby być częścią wydania ASP.NET MVC.

+0

RenderPartial ("Product/Single") będzie działać dla podkatalogu w folderze Product View. Właśnie użyłem tej techniki dla niektórych widoków cząstkowych, które chcę zachować w podkatalogu od reszty ASPX/ASCX skojarzonych z kontrolerem. – RichardOD

5

Bo dzwoni RenderAction() z widokiem na Produktu

...

Nie rozumiem, dlaczego potrzebne podać pełną ścieżkę do widzenia. To miałoby sens do mnie względna nazwa należy interpretować względem ścieżki bieżącego widoku za zamiast ścieżki zobaczyć oryginalny sterownika

Część Myślę, że nieporozumienie jest „położenie wykonanie "z braku lepszego lub oficjalnego terminu. Ścieżki nie są względne w stosunku do widoku, ani nawet "widoku kontrolera", jak to określasz. Są one względem adresu URL żądania, który definiuje kontekst kontrolera. Być może nie mówię tego zbyt dobrze, ale jeśli spędzicie trochę czasu w Reflectorze, analizując, jak adresy URL i trasy są rozwiązywane, myślę, że to wszystko wpadłoby w wasze głowy.

+0

To, co powiedziałeś, ma sens. –

+0

Zachowanie ma sens, ale nie ma dla mnie sensu, dlaczego taki byłby projekt. Nie sądzę, aby kod w widoku musiał być świadom drogi, z której jest wywoływany. –

2

Od patrząc na próbce MVCStoreFront to jak mają wszystko strukturalnego do wywoływania renderPartial

Views 
    Shared 
     ProductSingle 
     ProductList 
     ArticleSingle 
     ArticleList 

Następnie czyni je poprzez:

<% Html.RenderPartial("ProductSingle", ViewData["ProductList"]); %> 
<% Html.RenderPartial("ProductList", product); %> 
<% Html.RenderPartial("ArticleSingle", article); %> 
<% Html.RenderPartial("ArticleList", ViewData["ArticleList"]); %>