Dlaczego Editor Template jest lepszy niż Partial View do tworzenia formularzy?

Wprowadzenie

W ASP.NET MVC rozbudowane formularze możemy utworzyć na różne sposoby. Na ogół staramy się wyrzucać powtarzające się elementy do oddzielnych plików, aby wykorzystywać je ponownie. Zauważyłem, że większość osób do tego celu wykorzystuje widoki Partial, które niestety często zamiast pomóc – powodują dodatkowe problemy. W tym wpisie postaram się pokazać Ci , dlaczego w przypadku formularzy lepiej użyć Editor Templates niż widoków Partial.

Przykład

Zacznę od przykładu, abyś wiedział lub wiedziała, co chcemy osiągnąć i jaki będziemy mieli problem. W testowej aplikacji chcemy umożliwić edycję danych użytkownika. Użytkownik, poza podstawowymi danymi, ma również dane adresowe. Z racji tego, że te dane możemy mieć w różnych miejscach naszej aplikacji (np. sam użytkownik może mieć adres zamieszkania, adres korespondencyjny, adres do faktury), chcemy ten fragment formularza mieć zdefiniowany w innym pliku, aby używać do wielokrotnie.

Przygotowałem dwa viewmodele – jeden dla danych adresowych, drugi dla danych użytkownika:

Jak widać klasa User zawiera właściwość typu AddressViewModel dla danych adresowych.

Zobaczmy, jak zachowa się formularz zbudowany przy wykorzystaniu widoku Partial.

Partial View

Do aplikacji dodałem bardzo prosty UsersController, który zawiera po dwie akcje dla każdego z przykładów (jedna akcja dla GET, druga dla POST). Akcje są bardzo proste i zwracają po prostu widok:

Ciekawsze rzeczy dzieją się w samych widokach. Dla adresu utworzyłem nowy widok Partial w katalogu Views/Shared, aby można było go używać wielokrotnie w różnych kontrolerach. Widok wygenerowało Visual Studio na podstawie viewmodelu, w którym usunąłem cały kod związany z formularzem i zostawiłem same pola. Po tych zmianach widok wygląda tak:

Możemy go użyć teraz w innym widoku i dodać do jakiegoś istniejącego formularza. I tak też zrobiłem. Utworzyłem nowy widok w katalogu Views/Users dla akcji Partial z kontrolera UsersController. Podobnie jak wcześniej Visual Studio wygenerowało widok na podstawie viewmodelu, a na koniec użyłem widoku Partial (Html.Partial), aby wygenerować pola dla danych adresowych przez przycisk wysłania formularza. Ostateczny kod widoku wygląda tak:

Zwróć uwagę na linijkę 34, w której znajduje się użycie widoku Partial.

Sam widok w przeglądarce wygląda tak:

partial form

Aplikacja wyświetliła ładny formularz poprzez połączenie dwóch widoków.

Spójrzmy teraz na działanie tego widoku i to, w jaki sposób przesyła on dane do kontrolera.

Problem z widokiem Partial

Uzupełniłem dane w formularzu oraz przesłałem go do kontrolera. W akcji dla POST postawiłem breakpoint i zobaczyłem, jak uzupełnił dane model binder:

partial form debugger

Widać, że dane użytkownika (z UserViewModel) zostały ładnie wczytane do obiektu, natomiast dane adresowe już nie. Każda właściwość ma wartość null.

Dzieje się tak, ponieważ widok Partial w zły sposób generuje hmla widoku. Najlepiej widać to w narzędziu developerskim Chrome’a:

partial form html

Widać, że atrybut name inputa dla ulicy zawiera błędną wartość – („Street”), zamiast („Address.Street”). Dlatego model binder próbuje ustawić właściwość Street w UserViewModel, przez co właściwość Street w Address jest pusta.

Jednym ze sposobów rozwiązania tego problemu jest skorzystanie z tytułowych Editor Templates.

Darmowy kurs Visual Studio

Pracując z setkami programistów, zauważyłem, że większość osób nie pracuje efektywnie w Visual Studio. W skrajnych przypadkach korzystali z kopiowania z wykorzystaniem menu Edit. Wiem, że to dziwne, ale naprawdę niektórzy tak pracują. Dlatego postanowiłem stworzyć kurs Visual Studio – aby pomóc koleżankom i kolegom w efektywniejszej pracy.

Przygotowałem 20 lekcji e-mail, w których pokażę Ci, w jaki sposób pracować efektywniej i szybciej w Visual Studio. Poznasz dodatki, bez których nie wyobrażam sobie pracy w tym IDE.

Po więcej informacji zapraszam na dedykowaną stronę kursu: Darmowy Kurs Visual Studio.

Quiz C#

Ostatnio przygotowałem również quiz C#, w którym możesz sprawdzić swoją wiedzę. Podejmiesz wyzwanie?

Editor Template

Czym są szablony edycji? Jest to specjalny typ widoków partial, który jest przetwarzany przez ASP.NET MVC w nieco inny sposób. Przede wszystkim jest on związany między innymi z metodą EditorFor, której używamy w widokach do generowania kontrolek dla poszczególnych pól. Gdy użyjemy tej metody, ASP.NET MVC podczas generowania widoku szuka Editor Template dla danego typu danych (np. string, int czy nawet dla naszych własnych typów).

Od strony kodu jest to taki sam widok Partial (niczego w nim nie musimy zmieniać). Znajduje się w trochę innej lokalizacji oraz ma inną nazwę. Widoki te znajdują w się katalogu EditorTemplates (w katalogu Shared lub w katalogu z widokami dla danego kontrolera). Jeżeli natomiast chodzi o nazwę widoku, to najlepiej jakby była taka sama, jak nazwa typu, dla którego tworzymy szablon. W moim przypadku jest to AddressViewModel.cshtml:

editor templates solution explorer

W samym widoku użytkownika musimy użyć wspomnianej wyżej metody EditorFor, aby ASP.NET MVC użyło szablonu zamiast widoku Partial. Akcja EditorTemplate i widok dla niej w przykładzie zawiera tę zmianę. Sam poprawiony widok wygląda tak:

Jest on praktycznie identyczny jak poprzedni widok i różni się przede wszystkim linijką 34, w której jest „@Html.EditorFor(model => model.Address)” zamiast „@Html.Partial(„Address”, Model.Address)”.

Pod względem wizualnym wygenerowany widok jest identyczny i różni się on przede wszystkim wartościami atrybutu name inputów:

editor templates html

Gdy prześlemy dane do kontrola, widać, że wszystko ładnie zostało uzupełnione:

editor templates debugger

Przykład

Na githubie (https://github.com/danielplawgo/PartialForms) znajduje się przykład do tego wpisu. Testowa aplikacja, jak widać powyżej, zawiera dwie akcje ([adres]/Users/Partial oraz [adres]/Users/EditorTemplate), za pomocą których możesz sam/sama sprawdzić różnicę między działaniem widoku Partial a Editor Template.

Podsumowanie

Mam nadzieję, że po tym wpisie będziesz wiedział/wiedziała, dlaczego używanie widoków Partial do budowania formularzy to nienajlepszy pomysł. Niestety wiele razy widziałem aplikacje, w których programiści używali widoków Partial i później poświęcali wiele godzin, aby w jakiś sposób obejść ten problem. Na ogół tworzyli płaskie viewmodele, które później w kontrolerach mapowali (ręcznie lub za pomocą automappera) na zagnieżdżone obiekty. Utrzymanie tego kodu było później kosztowne, a można było to rozwiązać poprzez użycie Editor Templates.

W tym miejscu warto jeszcze wspomnieć, że w ASP.NET MVC istnieje drugi rodzaj szablonów (Display Templates), które działają w taki sam sposób (jedynie pliki znajdują w się w katalogu DisplayTemplates). Ich użycie odbywa się poprzez skorzystanie z metody DisplayFor.

A jakie są Twoje doświadczenia z widokami Partial oraz Editor Templates? Używasz tych drugich?

5 thoughts on “Dlaczego Editor Template jest lepszy niż Partial View do tworzenia formularzy?

  • Pingback: dotnetomaniak.pl
    • Hej Paweł!

      Masz racje można tak zrobić, ale według mnie na dłuższą metę takie rozwiązanie jest bardziej problematyczne niż Editor Templates. Szczególnie, gdy właściwości do adresu będą miały różne nazwy (np. użytkownik będzie miał 3 adresy: zamieszkania, korespondecyjny oraz do faktur).

  • Hmm wiekszym problemem wg mnie jest ze w takim projekcie dla jednej property potrzebujesz az 7 powtarzalnych linijek aby cos edytowac – sugerowalby jakis standardowy helper ktory by Ci wszystko dla jednej property robil (label, editorfor/inputbox, validationmessageFor) – bedzie bardziej przejrzyste i pozwoli pozbyc sie zbednych detali (dopoki nie robisz customowych rzeczy jest to wystarczajace)

    • Hej!
      Masz rację, jest to kolejny problem, która warto rozwiązać, aby tworzenie formularzy było jeszcze łatwiejsze. Porusze to w jednym z kolejnych wpisów.

      Dzięki za komentarz!

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *