Artykuł

lis 27 2010
0

Tworzenie stron z ASP.NET MVC2 w praktyce I

Blisko dwa lata temu, pisałem raczej teoretyczny tekst na temat Model View Controller, co w skrócie daje właśnie dzisiejszy tytułowy MVC. Celem tamtego wpisu, było ukazanie zależności jakie zachodzą pomiędzy poszczególnymi elementami witryn utworzonych przy użyciu tego wzorca projektowego. Przez ten czas, sama idea tego wzorca się nie zmieniła, ale pojawiły się nowe implementacje. Między innymi ASP.NET MVC2, który światło dzienne ujrzał wraz z premierą Visual Studio 2010 i pozwala na naprawdę szybkie i bezbolesne tworzenie rozbudowanych portali wykorzystujących bazy danych i inne cuda dostępne dziś w IT. Dzisiejszy wpis, po części oprze się na tutorialu dostępnym na oficjalnej stronie ASP.NET i można go znaleźć tutaj.

Założenia

W tutorialu, na którym po części zamierzam bazować, zbudowano aplikację, która pozwala na tworzenie bazy filmów. My stworzymy prosty manager kontaktów, w którym będziemy mogli trzymać informacje na temat naszych znajomych.

Aby zrealizować ten cel, przydatna okaże się baza danych. Możemy w tylu celu wykorzystać SQL Server 2008 R2 Express.

Potrzebne będzie również Visual Studio 2010, które zostało wyposażone w biblioteki do ASP.NET MVC 2.

Jeśli mamy wszystkie składniki, to możemy przystąpić do pracy.

Tworzymy projekt

Aby utworzyć nową stronę w technologii ASP.NET MVC 2, z menu File wybieramy podmenu New, a następnie opcję Web Site.... Na naszym ekranie pojawi się okienko dialogowe widoczne na screenie 1.

Opcje ustawiamy tak jak na dialogu, czyli wybieramy ASP.NET MVC 2 Web Application. Określamy również nazwę oraz docelową lokalizację. Po zatwierdzeniu dialogu, Visual Studio zapyta nas, czy chcemy utworzyć unit testowy dla naszej aplikacji. Możemy mu w tym momencie podziękować.

Po zatwierdzeniu wszystkiego co Visual Studio miał nam do zaoferowania, zostanie utworzona nowa aplikacja (screen 2). Jak widać, Visual Studio utworzył już za nas podstawowe witryny aplikacji. Mamy tutaj katalogi między innymi dla kontrolerów, modeli, widoków. Zgodnie z tym, co napisałem w pierwszym wpisie o MVC na tej stronie dwa lata temu, każdy z tych elementów ma swoją rolę do odegrania.

Dla przypomnienia, scharakteryzuję na szybko zadania każdego z elementów:

  • Kontroler - główny element każdej aplikacji MVC. Odpowiedzialny jest za przyjmowanie i obsługę żądań oraz tworzenie więzi pomiędzy widokiem, a modelem
  • Model - element odpowiedzialny za obsługę logiki biznesowej, może to być np. model bazy danych
  • Widok - element odpowiedzialny za warstwę prezentacji. Może wyświetlać dane przetworzone przez model

Skoro mamy już jakieś pojęcie na temat tego co chcemy stworzyć, wiemy też jak działa MVC i mamy już utworzony projekt, to możemy przejść dalej. Na początek, wyczyścimy naszą witrynę ze zbędnych elementów.

Czyszczenie projektu

Wybierając ten typ projektu w Visual Studio, otrzymujemy można by powiedzieć częściowo gotową aplikację. Na początku, możemy spróbować uruchomić projekt (zielona strzałka na pasku narzędzi). Powinniśmy ujrzeć naszą stronę w oknie przeglądarki i to nawet z działającymi funkcjonalnościami. Możemy sobie teraz trochę poklikać:)

Kiedy już skończymy się bawić projektem (warto wiedzieć, że Visual Studio umożliwia tworzenie również pustych projektów ASP.NET MVC 2), to możemy zacząć go czyścić ze zbędnych elementów. Modyfikować będziemy, zawartość trzech katalogów: Controllers, Models oraz Views.

Controllers

W tym przypadku, sprawa jest prosta. Usuwamy AccountController.cs. Drugi z plików, pozostawiamy bez zmian.

Models

W katalogu modeli, podobnie jak w katalogu kontrolerów. Usuwamy plik AccountModels.cs.

Views

Najwięcej pracy, czeka nas w katalogu Views. Najpierw, usuwamy cały katalog Account. Dzięki temu, pozbędziemy się powiązań z wcześniej usuniętym kontrolerem oraz modelem.

Następnie, zajmiemy się zawartością katalogu Views/Shared. Na początek, usuwamy plik LogOnUserControl.ascx.

Na koniec, została nam najcięższa praca w tej materii. Musimy wyedytować plik szablonu (przeczytaj więcej oszablonach stron WWW) Site.Master.

Usuwamy następujący kod: (powinien się on znajdować około linii 18)

<div id="logindisplay">
    <% Html.RenderPartial("LogOnUserControl"); %>
</div>

W ten sposób, pozbyliśmy się już kompletnie mechanizmu logowania. Możemy również zmienić tytuł strony, oraz zlokalizować ją ogólnie - nie będę tutaj jednak opisywał jak bawić się z HTMLem;)

Tworzenie bazy danych

Czas utworzyć bazę danych. Nie będzie ona w żaden sposób skomplikowana, bo będzie zawierać tylko jedną tabelę. Dla praktyki, moglibyśmy utworzyć ją wklepując polecenia SQL w SQL Sever Management Studio, ale dziś zademonstruję inny sposób. Naszą bazę danych utworzymy z poziomu Visual Studio:)

Uruchamiamy Visual Studio i otwieramy nasz projekt (jeśli wcześniej go zamknęliśmy). Następnie musimy dostać się do panelu Server Explorer. Jeśli nie jest on widoczny na ekranie, możemy go włączyć z poziomu menu (View - Other Windows - Server Explorer). W panelu wybieramy opcję Connect to Database (patrz screen 3). Na ekranie, pojawi się nowe okno, w którym musimy uzupełnić dane naszego połączenia (mniej więcej tak jak na screenie 4).

Na początek, klikamy na strzałkę w polu Server name po małej chwili powinna nam się pojawić na liście nazwa naszego komputera (w przypadku serwera SQLEXPRESS, być może konieczny będzie dopisek \SQLEXPRESS do nazwy hosta), wybieramy go.

Następnie, wybieramy sposób logowania do serwera. Sposób ten zależy od opcji wybranych podczas instalacji serwera bazy danych. Ja preferuje wykorzystanie do tego celu użytkownika bazy danych.

Na samym końcu, wprowadzamy nazwę bazy danych, która ma docelowo zostać utworzona. Możemy teraz przetestować nasze ustawienia przyciskiem Test connection. Jeśli wszystkie dane są prawidłowe, to zostaniemy poproszeni o potwierdzenie chęci utworzenia nowej bazy danych (screen 5). Oczywiście to było naszym celem, tak więc radośnie się zgadzamy.

Po tej operacji, powinniśmy ujrzeć nowe połączenie do bazy danych w Server Explorerze (screen 6).

Tworzenie tabeli

Mamy już bazę danych, na dodatek podpiętą nawet do projektu. Niestety w tej chwili niewiele nam to daje, bo jest ona pusta. Trzeba dodać jakąś tabelę...

Aby dodać tabelę, rozwijamy drzewko z połączeniem naszej bazy danych, odnajdujemy katalog Tables i klikamy na niego PPM. Z menu kontekstowego wybieramy opcję Add new table. Skutkiem tej operacji, będzie otwarcie nowego okna, w którym zdefiniujemy pola oraz właściwości naszej tabeli (wszystko to zrobimy w sposób graficzny!).

Czas na utworzenie pól tabeli i ustawienie właściwości tejże tabeli. Generalnie naszym celem, jest uzyskanie efektu przedstawionego na screenie 8 (proszę zwrócić uwagę również na ustawienia właściwości widoczne w prawej części okna np. na kolumnę identity). Jeśli dojdziemy do struktury przedstawionej na screenie 8, to klikamy prawym przyciskiem myszy na pierwszy wiersz i wybieramy opcję Set Primary Key, która ustawi nam klucz podstawowy na pole PersonId. Jeśli zamiast graficznego edytora, wolisz klasyczny SQL, z pomocą przyjdzie Ci poniższe polecenie:

CREATE TABLE [dbo].[Persons](
    [PersonId] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [PersonFirstName] [varchar](50) NOT NULL,
    [PersonLastName] [varchar](50) NOT NULL,
    [PersonAge] [int] NOT NULL,
    [PersonPhone] [int] NULL
) ON [PRIMARY]
GO

Niezależnie od wybranego sposobu, otrzymamy ten sam efekt. Jak widać, tabela nie jest przesadnie skomplikowana i zawiera podstawowe dane osobowe. Wszystkie pola poza numerem telefonu są wymagane. Dodatkowo, pole PersonId ma własność Identity. Dzięki temu, odpowiedzialność nadawania kolejnych numerów identyfikacyjnych spada na bazę.

Dodawanie danych

Dane do naszej tabeli, możemy również dodać w sposób graficzny. Wystarczy kliknąć PPM na nazwie tabeli i wybrać opcję Show table data (screen 9). Na ekranie ukaże się pusta tabelka, którą możemy po prostu wypełnić, bez żadnego programowanie (prawie jak w Wordzie:)).

Tak więc, wypełniamy ją przykładowymi danymi i zapisujemy wszystko. Jesteśmy gotowi, do utworzenia modelu:)

Tworzenie modelu

Czas na stworzenie modelu, który można powiedzieć, że stanie się fundamentem całej naszej aplikacji, ponieważ będzie odpowiedzialny za kontakty z bazą. Klikamy PPM na katalogu Models i wybieramy opcję Add new class.

Na nowym ekranie, który się pojawi odszukujemy pozycję ADO.NET Entity Data Model (screen 10). Nowo utworzonemu tworowi nadajemy nazwę Person.edmx. Zatwierdzenie okna, spowoduje uruchomienie kreatora tworzenia modelu bazy.

Na pierwszym ekranie, wybieramy opcję Generate from Database i przechodzimy ładnie dalej.

Na drugim ekranie, wybieramy nasze źródło danych oraz godzimy się na dołączenie wrażliwych danych w Connection stringu (oczywiście przy tworzeniu bardziej rozbudowanych i poważnych aplikacji, należy uważać z tą opcją - screen 11). Możemy przejść dalej.

W kolejnym kroku, wybieramy wcześniej utworzoną tabelę oraz zaznaczamy opcję Pluralize or singularize generated object names (screen 12). Możemy teraz zakończyć kreator tworzenia modelu.

Rozbudowa kontrolera

Nasza aplikacja, ma już solidne podstawy by w końcu zaoferować użytkownikom jakąś fajną funkcjonalność. Aby to uczynić, musimy rozbudować HomeController. W chwili obecnej jego konstrukcja powinna wyglądać mniej więcej tak (pominę odwołania do usingów):

namespace PersonMvc.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            return View();
        }

        public ActionResult About()
        {
            return View();
        }
    }
}

Jak widać, kod nie jest przesadnie skomplikowany. Najważniejszym elementem tego kodu, są dwie metody zwracające obiekt ActionResult.

ActionResult, to specjalny typ obiektu, który pozwala na zwracanie przypisanego dla tej akcji widoku (kod return View() na końcu każdej metody). Wszystkie widoki uporządkowane są w katalogi charakterystyczne dla własnych kontrolerów. Np. widoki dla tego kontrolera, znajdują się w ścieżce Views/Home (ucinane jest zawsze słowo Controller). Pliki aspx widoków mają dokładnie takie same nazwy jak odpowiadające im metody i korzystają z pliku szablonu, o którym mówiliśmy już wcześniej.

Oczywiście ActionResult, możemy zastąpić jakimś innym typem. Np. stringiem, co spowoduje, że metoda ta wyświetli na ekranie string zwrócony instrukcją return.

Jeśli to wszystko nie jest dla Ciebie do końca jasne, to nie martw się. Teraz dodamy naszą własną metodę do kontrolera co powinno trochę rozjaśnić sprawy:)

Dodawanie metody listującej

Zrobiliśmy już dość duży wstęp i przygotowaliśmy model. Czas zrobić z niego pierwszy użytek. Naszym celem będzie utworzenie czegoś na kształt listy kontaktów: Czas rozpocząć pracę.

Na początek, dodajemy using do modeli:

using PersonMvc.Models;

Następnie na początku klasy, dodajemy pole będące obiektem naszego modelu oraz brakujący konstruktor, który otworzy obiekt naszego modelu podczas inicjalizacji klasy:

private PersonsEntities m_oPersonsEntities = null;

public HomeController()
{
    m_oPersonsEntities = new PersonsEntities();
}

Ostatnim krokiem jaki wykonamy w kontrolerze, będzie stworzenie metody List, który kod wygląda następująco:

public ActionResult List()
{
    var oPersons = from oPerson in m_oPersonsEntities.People
                    select oPerson;
    return View(oPersons.ToList());
}

Odwołaliśmy się do modelu, który w tej chwili jest naszym polem klasy i stworzyliśmy tutaj proste zapytanie LINQ.

Na koniec, zwracamy te dane do widoku (który zaraz utworzymy) za pomocą metody View, której jedna z postaci pozwala na przekazanie dowolnego obiektu i wykorzystuje się ją do przekazywania danych, które zostaną później wyświetlone na stronie.

Kolejnym krokiem będzie utworzenie widoku, dla naszej nowo stworzonej metody.

Tworzymy widok dla metody listującej

Tak jak pisałem wcześniej, widoki tworzymy pod kątem konkretnych metod, czyli notabene akcji. Widoki tworzy się najłatwiej z poziomu kontrolera. Otwieramy nasz kontroler i ustawiamy się kursorem wewnątrz metody List i klikamy tam PPM. Z menu kontekstowego wybieramy opcję Add View (screen 13).

Na ekranie pojawi się nowe okienko, które wypełniamy w sposób ukazany na screenie 14. Musimy wybrać dokładnie takie opcje, omówię je teraz pokrótce:

  • Create partial view (nie zaznaczamy) - umożliwia stworzenie kontrolki, do wielokrotnego wykorzystania w projekcie
  • Create strongly-typed view (zaznaczamy) - umożliwia stworzenie widoku silnie typowanego, oznacza to, że będzie on wykorzystywać jedną z klas modelu dostępna w projekcie
  • View content (wybieramy List) - zaznaczenie pola wyboru przy poprzedniej opcji, umożliwi nam automatyczne wygenerowanie kilku rodzajów stron na podstawie informacji zawartych w modelu. Jedną z nich jest lista, która wyświetli wszystkie pozycje uwarunkowane zapytaniem napisanym wcześniej w kontrolerze:)
  • Select master page - pozostawiamy te ustawienie tak jest domyślnie, czyli zaznaczone. Dzięki temu, wykorzystamy szablon strony, który wcześniej edytowaliśmy

Jeśli wszystko zrobiliśmy dobrze, to możemy zatwierdzić dialog. Efektem tego, będzie gotowy widok:) Visual Studio w tym aspekcie, naprawdę ułatwia życie. Możemy oczywiście ten widok modyfikować, zmienić np. nazwy kolumn na polskie itp. Ja osobiście usunąłem odnośnik do detali, ponieważ taka funkcjonalność nie będzie implementowana. Resztę, zostawiam waszej własnej inwencji:)

Poruszanie się po witrynie

Napisaliśmy dziś kawał kodu, a jeszcze więcej wygenerowało go za nas środowisko:). Pora więc powoli kończyć pierwszą cześć wpisu na temat ASP.NET MVC2. Jednak zanim skończymy, powinniśmy się dowiedzieć, jak obsługiwać tę aplikację, czyli generalnie jak korzystać z wywołań kontrolerów.

Kiedy uruchomimy aplikację, to adres w przeglądarce będzie wyglądać mniej więcej tak: (port uzależniony jest od aktualnych ustawień lokalnego serwera)

http://localhost:16180/

Zostanie w tym przypadku wywołany domyślny kontroler - czyli HomeController. Jeśli wykorzystalibyśmy adres:

http://localhost:16180/Home/

To ku naszemu zdziwieniu zdziwieniu, wyświetli się dokładnie taka sama strona. Jak to się dzieje? Sprawa jest prosta. HomeController, jest kontrolerem domyślnym, dlatego jeśli nie podamy żadnych dodatkowych informacji to zostanie on uruchomiony domyślnie. Dociekliwi czytelnicy zapytają - a czemu w pasku adresu nie ma słowa Controller tylko samo Home? Dzieje się tak dlatego, że słówko to jest używane bardziej w hierarchii kodu, a w samej nawigacji jest już domyślnie pomijane, bo tak jest jednak bardziej intuicyjnie.

Kombinujmy jednak dalej. Co się stanie jeśli w przeglądarce otworzymy taki adres:

http://localhost:16180/Home/Index

Również wyświetli się ta sama strona:) A dlaczego? Bo idąc poprzednim tokiem rozumowania, metoda Index, zawsze będzie tą domyślną, zresztą podobnie jest w Internecie. Zawsze to plik typu, index.html, index.php itd. jest tym głównym

Podsumujmy teraz zebraną wiedzę, sposób wywoływania akcji w stronie opartej o ASP.NET MVC2 jest następujący:

http://serwer:[port]/kontroler/nazwa_metody/

Ale to nie wszystko, za nazwą metody, mogą się znajdować parametry przeznaczone dla tej metody, ale o tym powiemy szerzej w części następnej.

Na koniec, spójrzmy co się stanie, jeśli w pasku przeglądarki podamy mniej więcej taki adres:

http://localhost:16180/Home/List

Jak nie trudno się domyślić, efektem tego będzie nasza piękna lista (screen 15). Później dowiemy się o tym, jak utworzyć linki pomiędzy poszczególnymi podstronami.

Podsumowanie

Czas zakończyć pierwszą część wpisu na temat ASP.NET MVC2. Myślę, że zrobiliśmy dziś całkiem sporo. Ogrom materiału, który trzeba przyswoić (jak również go opisać), zmusił mnie nie jako do podzielenia tego wpisu na części. Dziś udało nam się zmodyfikować istniejący kontroler, utworzyć model oraz widok. Dowiedzieliśmy się również jak dopasować stronę do naszych potrzeb.

W kolejnej części (a być może nawet częściach), postaram się opisać dodawanie nowych rekordów oraz zarządzanie tymi istniejącymi. Dodamy również trochę kodu, który wspomoże walidację formularzy.

P.S. Gotowy projekt, wraz z kilkoma prostymi usprawnieniami, znajduje się w dziale Download:)

ERRATA - baza danych

Jeśli realizowałeś kroki tego tutoriala przed 4 stycznia 2011 - przeczytaj koniecznie.

W trakcie generowania polecenia tworzącego skrypt tabeli wkradł się błąd. Nie zdefiniowano klucza głównego. Aby dodać ten klucz, należy wykonać zapytanie na bazie danych:

USE Persons
ALTER TABLE Person
	ADD CONSTRAINT PK_PersonId PRIMARY KEY(PersonId)

Należy również utworzyć od nowa model bazy danych, według kroków powyżej - kasujemy bieżący i tworzymy od nowa.

Data ostatniej modyfikacji: 22.10.2012, 15:01.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus