W ASP.NET MVC 6.0 (ASP.NET 5.0) usunięto metodę Html.Action. Służyła ona głównie do generowania widoków częściowych. Na przykład, jeśli jakąś funkcjonalność mieliśmy na każdej stronie, wtedy warto było stworzyć child-action i renderować osobno każdą część. Tworzyliśmy wtedy osobny widok i akcję w kontrolerze. Główny widok wywoływał daną akcję (child-action) na kontrolerze i renderował wskazaną część. Więcej o ChildAction można poczytać tutaj.
Dlaczego zatem Html.Action został usunięty? Zdecydowano, że stare rozwiązanie nie było zbyt intuicyjne… Osobiście nie miałem z nim większych problemów, aczkolwiek ViewComponents jest również dobrym podejściem.
Załóżmy, że chcemy wyświetlać baner na każdej podstronie. Dla uproszczenia, nasz baner będzie po prostu zawierał aktualny czas:
public class BannerViewComponent:ViewComponent { public IViewComponentResult Invoke(int itemsCount) { DateTime[] data = new DateTime[itemsCount]; for (int i = 0; i < itemsCount; i++) data[i] = DateTime.Now; return View(data); } }
Zwracamy zawsze IViewComponentResult i metoda powinna nazywać się Invoke. Z kolei typ i liczba parametrów są dowolne. W naszym przypadku przekazywany jest parametr itemsCount. Mamy tutaj pełną dowolność. Kolejny etap to stworzenie widoku, wyświetlającego przekazaną listę DateTime:
@model System.DateTime[] <h3>Sample</h3> @foreach (var dateTime in Model) { <p>@dateTime</p> }
W widoku nie ma nic nadzwyczajnego. Czysty szablon razor. Należy jednak pamiętać, aby nazwać go Default.cshtml i umieścić w folderze Views/{nazwa kontrolera}/Components/Banner.
W głównym widoku z kolei wywołujemy po prostu:
@Component.Invoke("Banner", 5);
Drugi parametr to ItemsCount, który służy nam jako parametr wejściowy do ViewComponent. Myślę, że kod wygląda bardziej przejrzyście niż w przypadku Action, ale nie stanowi dla mnie to jakieś wielkiej różnicy. Intencja jest bardziej jasna z ViewComponent, ale moim zdaniem usunięcie starej metody spowoduje więcej problemów niż korzyści.