Część 3. Dodawanie widoku do aplikacji MVC platformy ASP.NET Core

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.

Ostrzeżenie

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To w przejrzysty sposób enkapsuluje proces generowania odpowiedzi HTML dla klienta.

Szablony widoków są tworzone przy użyciu polecenia Razor. szablony widoków oparte na Razor:

  • Mieć rozszerzenie pliku .cshtml.
  • Zapewnij elegancki sposób tworzenia danych wyjściowych HTML za pomocą języka C#.

Index Obecnie metoda zwraca ciąg z komunikatem w klasie kontrolera. HelloWorldController W klasie zastąp metodę Index następującym kodem:

public IActionResult Index()
{
    return View();
}

Powyższy kod:

  • Wywołuje metodę View kontrolera.
  • Używa szablonu widoku do generowania odpowiedzi HTML.

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład metoda akcji Index w powyższym kodzie.
  • Zazwyczaj zwracaj obiekt IActionResult lub klasę pochodną od ActionResult, a nie typ taki jak string.

Dodawanie widoku

Kliknij prawym przyciskiem myszy folder Views , a następnie dodaj > nowy folder i nadaj nazwę folderowi HelloWorld.

Kliknij prawym przyciskiem myszy folder Views/HelloWorld, a następnie dodaj >nowy element.

W oknie dialogowym Dodawanie nowego elementu , jeśli opcja Pokaż wszystkie szablony jest dostępna, wybierz ją.

W oknie dialogowym Dodawanie nowego elementu — MvcMovie:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybierz Razor Widok — Pusty
  • Zachowaj wartość pola Nazwa, Index.cshtml.
  • Wybierz Dodaj

Okno dialogowe Dodawanie nowego elementu.

Zastąp zawartość Views/HelloWorld/Index.cshtmlRazor pliku widoku następującymi elementami:

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

Przejdź do https://localhost:{PORT}/HelloWorld:

  • Metoda Index w HelloWorldController uruchomiła instrukcję return View();, która określała, że metoda powinna użyć pliku szablonu widoku do wygenerowania odpowiedzi w przeglądarce.

  • Nie określono nazwy pliku szablonu widoku, więc domyślnie MVC używa domyślnego pliku widoku. Gdy nazwa pliku widoku nie jest określona, zwracany jest widok domyślny. Widok domyślny ma taką samą nazwę jak metoda akcji w Index tym przykładzie. Szablon widoku /Views/HelloWorld/Index.cshtml jest używany.

  • Na poniższej ilustracji przedstawiono ciąg "Hello from our View Template!" (Witaj z naszego szablonu widoku) zakodowany w widoku:

    Okno przeglądarki.

Zmienianie widoków i stron układu

Wybierz łącza menu MvcFilm, Homei Privacy. Każda strona zawiera ten sam układ menu. Układ menu jest implementowany w Views/Shared/_Layout.cshtml pliku.

Otwórz plik Views/Shared/_Layout.cshtml.

Szablony układów umożliwiają:

  • Określanie układu kontenera HTML witryny w jednym miejscu.
  • Stosowanie układu kontenera HTML na wielu stronach w witrynie.

Znajdź wiersz @RenderBody(). RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie strony właściwe dla danego widoku, które tworzysz, osadzone w stronie układu. Jeśli na przykład klikniesz link Privacy, widok Views/Home/Privacy.cshtml zostanie wyrenderowany wewnątrz metody RenderBody.

Zastąp zawartość Views/Shared/_Layout.cshtml pliku następującym znacznikiem. Zmiany są wyróżnione:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie App</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/MvcMovie.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="HelloWorld" asp-action="Index">Movie App</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2025 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

Powyższe oznaczenie wprowadziło następujące zmiany:

  • Trzy wystąpienia w zakresie od MvcMovie do Movie App.
  • Element zakotwiczenia <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> do <a class="navbar-brand" asp-area="" asp-controller="HelloWorld" asp-action="Index">Movie App</a>.

W poprzednim kodzie znacznika pominięto asp-area=""atrybut pomocnika tagów Anchor oraz jego wartość, ponieważ ta aplikacja nie używa Areas.

Zapisz zmiany i wybierz łącze Privacy. Zwróć uwagę, że tytuł na karcie przeglądarki wyświetla Privacy Polityka - Movie App zamiast Privacy Polityka - MvcMovie

Privacy Zakładka.

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst kotwicy są wyświetlane jako Movie App. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Przejrzyj plik Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml dołącza plik Views/Shared/_Layout.cshtml do każdego widoku. Właściwość Layout może służyć do ustawiania innego widoku układu lub ustawiania go na null wartość , aby żaden plik układu nie był używany.

Views/HelloWorld/Index.cshtml Otwórz plik widoku.

Zmień tytuł i element <h2>, jak wyróżniono poniżej:

@{
    ViewData["Title"] = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

Tytuł i <h2> element są nieco inne, więc jest jasne, która część kodu zmienia ekran.

ViewData["Title"] = "Movie List"; w powyższym kodzie ustawia właściwość Title słownika ViewData na „Lista filmów”. Właściwość Title jest używana w elemecie <title> HTML na stronie układu:

<title>@ViewData["Title"] - Movie App</title>

Zapisz zmiany i przejdź do https://localhost:{PORT}/HelloWorld.

Zwróć uwagę, że zmieniono następujące elementy:

  • Tytuł przeglądarki.
  • Nagłówek podstawowy.
  • Nagłówki pomocnicze.

Jeśli w przeglądarce nie ma żadnych zmian, może to być buforowana zawartość, która jest przeglądana. Naciśnij Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony przy użyciu elementu ViewData["Title"], który ustawiamy w szablonie widoku Index.cshtml, oraz dodatkowego ciągu „- Movie App” dodanego w pliku layoutu.

Zawartość szablonu Index.cshtml widoku jest scalona z szablonem Views/Shared/_Layout.cshtml widoku. Pojedyncza odpowiedź HTML jest wysyłana do przeglądarki. Szablony układów ułatwiają wprowadzanie zmian, które mają zastosowanie na wszystkich stronach w aplikacji. Aby dowiedzieć się więcej, zobacz Układ.

Widok listy filmów.

Mały fragment „danych”, komunikat „Hello from our View Template!”, jest jednak wpisany na stałe w kodzie. Aplikacja MVC ma jeszcze "V" (widok), "C" (kontroler), ale nie "M" (model).

Przekazywanie danych z kontrolera do widoku

Akcje kontrolera są wywoływane w odpowiedzi na przychodzące żądanie adresu URL. Klasa kontrolera to miejsce, w którym jest napisany kod, który obsługuje przychodzące żądania przeglądarki. Kontroler pobiera dane ze źródła danych i decyduje, jakiego typu odpowiedź ma być wysyłana z powrotem do przeglądarki. Szablony widoków mogą być używane z poziomu kontrolera do generowania i formatowania odpowiedzi HTML dla przeglądarki.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych, aby szablon widoku mógł wyrenderować odpowiedź.

Szablony widoku nie powinny:

  • Wykonaj logikę biznesową
  • Bezpośrednia interakcja z bazą danych.

Szablon widoku powinien działać tylko z danymi dostarczonymi przez kontroler. Utrzymanie tego "rozdzielenia problemów" pomaga zachować kod:

  • Czysty.
  • Testowalny.
  • Łatwy w utrzymaniu.

Obecnie metoda Welcome w klasie HelloWorldController przyjmuje parametr name i parametr ID, a następnie wypisuje wartości bezpośrednio w przeglądarce.

Zamiast renderować tę odpowiedź jako ciąg znaków w kontrolerze, zmień kontroler tak, aby zamiast tego używał szablonu widoku. Szablon widoku generuje dynamiczną odpowiedź, co oznacza, że odpowiednie dane muszą zostać przekazane z kontrolera do widoku w celu wygenerowania odpowiedzi. W tym celu kontroler umieszcza dane dynamiczne (parametry), których potrzebuje szablon widoku w słowniku ViewData . Następnie szablon widoku może uzyskiwać dostęp do danych dynamicznych.

W pliku HelloWorldController.cs zmień metodę Welcome, aby dodać do słownika ViewData wartości Message i NumTimes.

Słownik ViewData jest obiektem dynamicznym, co oznacza, że można użyć dowolnego typu. Obiekt ViewData nie ma zdefiniowanych właściwości, dopóki coś nie zostanie dodane. System powiązania modelu MVC automatycznie mapuje nazwane parametry name i numTimes z ciągu zapytania na parametry w metodzie . Cały HelloWorldController:

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers;

public class HelloWorldController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
    public IActionResult Welcome(string name, int numTimes = 1)
    {
        ViewData["Message"] = "Hello " + name;
        ViewData["NumTimes"] = numTimes;
        return View();
    }
}

Obiekt słownika ViewData zawiera dane, które zostaną przekazane do widoku.

Utwórz szablon widoku powitalnego o nazwie Views/HelloWorld/Welcome.cshtml.

Utworzysz pętlę w szablonie Welcome.cshtml widoku, który wyświetla komunikat "Hello" NumTimes. Zastąp zawartość Views/HelloWorld/Welcome.cshtml pliku następującym kodem:

@{
    ViewData["Title"] = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < (int)ViewData["NumTimes"]!; i++)
    {
        <li>@ViewData["Message"]</li>
    }
</ul>

Zapisz zmiany i przejdź do następującego adresu URL:

https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4

Dane są pobierane z adresu URL i przekazywane do kontrolera za pomocą mechanizmu wiązania modelu MVC. Kontroler pakuje dane do słownika ViewData i przekazuje ten obiekt do widoku. Następnie widok renderuje dane jako HTML w przeglądarce.

Privacy widok przedstawiający etykietę powitalną i frazę Hello Rick pokazaną cztery razy.

W poprzednim przykładzie użyto słownika ViewData, aby przekazać dane z kontrolera do widoku. W dalszej części samouczka model widoku jest używany do przekazywania danych z kontrolera do widoku. Podejście modelu widoku do przekazywania danych jest preferowane w przypadku podejścia do słownika ViewData .

W następnym samouczku zostanie utworzona baza danych o filmach.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To w przejrzysty sposób enkapsuluje proces generowania odpowiedzi HTML dla klienta.

Szablony widoków są tworzone przy użyciu polecenia Razor. szablony widoków oparte na Razor:

  • Mieć rozszerzenie pliku .cshtml.
  • Zapewnij elegancki sposób tworzenia danych wyjściowych HTML za pomocą języka C#.

Index Obecnie metoda zwraca ciąg z komunikatem w klasie kontrolera. HelloWorldController W klasie zastąp metodę Index następującym kodem:

public IActionResult Index()
{
    return View();
}

Powyższy kod:

  • Wywołuje metodę View kontrolera.
  • Używa szablonu widoku do generowania odpowiedzi HTML.

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład metoda akcji Index w powyższym kodzie.
  • Zazwyczaj zwracaj obiekt IActionResult lub klasę pochodną od ActionResult, a nie typ taki jak string.

Dodawanie widoku

Kliknij prawym przyciskiem myszy folder Views , a następnie dodaj > nowy folder i nadaj nazwę folderowi HelloWorld.

Kliknij prawym przyciskiem myszy folder Views/HelloWorld, a następnie dodaj >nowy element.

W oknie dialogowym Dodawanie nowego elementu , jeśli opcja Pokaż wszystkie szablony jest dostępna, wybierz ją.

W oknie dialogowym Dodawanie nowego elementu — MvcMovie:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybierz Razor Widok — Pusty
  • Zachowaj wartość pola Nazwa, Index.cshtml.
  • Wybierz Dodaj

Okno dialogowe Dodawanie nowego elementu

Zastąp zawartość Views/HelloWorld/Index.cshtmlRazor pliku widoku następującymi elementami:

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

Przejdź do https://localhost:{PORT}/HelloWorld:

  • Metoda Index w HelloWorldController uruchomiła instrukcję return View();, która określała, że metoda powinna użyć pliku szablonu widoku do wygenerowania odpowiedzi w przeglądarce.

  • Nie określono nazwy pliku szablonu widoku, więc domyślnie MVC używa domyślnego pliku widoku. Gdy nazwa pliku widoku nie jest określona, zwracany jest widok domyślny. Widok domyślny ma taką samą nazwę jak metoda akcji w Index tym przykładzie. Szablon widoku /Views/HelloWorld/Index.cshtml jest używany.

  • Na poniższej ilustracji przedstawiono ciąg "Hello from our View Template!" (Witaj z naszego szablonu widoku) zakodowany w widoku:

    Okno przeglądarki

Zmienianie widoków i stron układu

Wybierz łącza menu MvcFilm, Homei Privacy. Każda strona zawiera ten sam układ menu. Układ menu jest implementowany w Views/Shared/_Layout.cshtml pliku.

Otwórz plik Views/Shared/_Layout.cshtml.

Szablony układów umożliwiają:

  • Określanie układu kontenera HTML witryny w jednym miejscu.
  • Stosowanie układu kontenera HTML na wielu stronach w witrynie.

Znajdź wiersz @RenderBody(). RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie strony właściwe dla danego widoku, które tworzysz, osadzone w stronie układu. Jeśli na przykład klikniesz link Privacy, widok Views/Home/Privacy.cshtml zostanie wyrenderowany wewnątrz metody RenderBody.

Zastąp zawartość Views/Shared/_Layout.cshtml pliku następującym znacznikiem. Zmiany są wyróżnione:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie App</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/MvcMovie.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="HelloWorld" asp-action="Index">Movie App</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2025 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

Powyższe oznaczenie wprowadziło następujące zmiany:

  • Trzy wystąpienia w zakresie od MvcMovie do Movie App.
  • Element zakotwiczenia <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> do <a class="navbar-brand" asp-area="" asp-controller="HelloWorld" asp-action="Index">Movie App</a>.

W poprzednim kodzie znacznika pominięto asp-area=""atrybut pomocnika tagów Anchor oraz jego wartość, ponieważ ta aplikacja nie używa Areas.

Zapisz zmiany i wybierz łącze Privacy. Zwróć uwagę, że tytuł na karcie przeglądarki wyświetla Privacy Polityka - Movie App zamiast Privacy Polityka - MvcMovie

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst kotwicy są wyświetlane jako Movie App. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Przejrzyj plik Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml dołącza plik Views/Shared/_Layout.cshtml do każdego widoku. Właściwość Layout może służyć do ustawiania innego widoku układu lub ustawiania go na null wartość , aby żaden plik układu nie był używany.

Views/HelloWorld/Index.cshtml Otwórz plik widoku.

Zmień tytuł i element <h2>, jak wyróżniono poniżej:

@{
    ViewData["Title"] = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

Tytuł i <h2> element są nieco inne, więc jest jasne, która część kodu zmienia ekran.

ViewData["Title"] = "Movie List"; w powyższym kodzie ustawia właściwość Title słownika ViewData na „Lista filmów”. Właściwość Title jest używana w elemecie <title> HTML na stronie układu:

<title>@ViewData["Title"] - Movie App</title>

Zapisz zmiany i przejdź do https://localhost:{PORT}/HelloWorld.

Zwróć uwagę, że zmieniono następujące elementy:

  • Tytuł przeglądarki.
  • Nagłówek podstawowy.
  • Nagłówki pomocnicze.

Jeśli w przeglądarce nie ma żadnych zmian, może to być buforowana zawartość, która jest przeglądana. Naciśnij Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony przy użyciu elementu ViewData["Title"], który ustawiamy w szablonie widoku Index.cshtml, oraz dodatkowego ciągu „- Movie App” dodanego w pliku layoutu.

Zawartość szablonu Index.cshtml widoku jest scalona z szablonem Views/Shared/_Layout.cshtml widoku. Pojedyncza odpowiedź HTML jest wysyłana do przeglądarki. Szablony układów ułatwiają wprowadzanie zmian, które mają zastosowanie na wszystkich stronach w aplikacji. Aby dowiedzieć się więcej, zobacz Układ.

Widok listy filmów

Mały fragment „danych”, komunikat „Hello from our View Template!”, jest jednak wpisany na stałe w kodzie. Aplikacja MVC ma jeszcze "V" (widok), "C" (kontroler), ale nie "M" (model).

Przekazywanie danych z kontrolera do widoku

Akcje kontrolera są wywoływane w odpowiedzi na przychodzące żądanie adresu URL. Klasa kontrolera to miejsce, w którym jest napisany kod, który obsługuje przychodzące żądania przeglądarki. Kontroler pobiera dane ze źródła danych i decyduje, jakiego typu odpowiedź ma być wysyłana z powrotem do przeglądarki. Szablony widoków mogą być używane z poziomu kontrolera do generowania i formatowania odpowiedzi HTML dla przeglądarki.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych, aby szablon widoku mógł wyrenderować odpowiedź.

Szablony widoku nie powinny:

  • Wykonaj logikę biznesową
  • Bezpośrednia interakcja z bazą danych.

Szablon widoku powinien działać tylko z danymi dostarczonymi przez kontroler. Utrzymanie tego "rozdzielenia problemów" pomaga zachować kod:

  • Czysty.
  • Testowalny.
  • Łatwy w utrzymaniu.

Obecnie metoda Welcome w klasie HelloWorldController przyjmuje parametr name i parametr ID, a następnie wypisuje wartości bezpośrednio w przeglądarce.

Zamiast renderować tę odpowiedź jako ciąg znaków w kontrolerze, zmień kontroler tak, aby zamiast tego używał szablonu widoku. Szablon widoku generuje dynamiczną odpowiedź, co oznacza, że odpowiednie dane muszą zostać przekazane z kontrolera do widoku w celu wygenerowania odpowiedzi. W tym celu kontroler umieszcza dane dynamiczne (parametry), których potrzebuje szablon widoku w słowniku ViewData . Następnie szablon widoku może uzyskiwać dostęp do danych dynamicznych.

W pliku HelloWorldController.cs zmień metodę Welcome, aby dodać do słownika ViewData wartości Message i NumTimes.

Słownik ViewData jest obiektem dynamicznym, co oznacza, że można użyć dowolnego typu. Obiekt ViewData nie ma zdefiniowanych właściwości, dopóki coś nie zostanie dodane. System powiązania modelu MVC automatycznie mapuje nazwane parametry name i numTimes z ciągu zapytania na parametry w metodzie . Cały HelloWorldController:

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers;

public class HelloWorldController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
    public IActionResult Welcome(string name, int numTimes = 1)
    {
        ViewData["Message"] = "Hello " + name;
        ViewData["NumTimes"] = numTimes;
        return View();
    }
}

Obiekt słownika ViewData zawiera dane, które zostaną przekazane do widoku.

Utwórz szablon widoku powitalnego o nazwie Views/HelloWorld/Welcome.cshtml.

Utworzysz pętlę w szablonie Welcome.cshtml widoku, który wyświetla komunikat "Hello" NumTimes. Zastąp zawartość Views/HelloWorld/Welcome.cshtml pliku następującym kodem:

@{
    ViewData["Title"] = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < (int)ViewData["NumTimes"]!; i++)
    {
        <li>@ViewData["Message"]</li>
    }
</ul>

Zapisz zmiany i przejdź do następującego adresu URL:

https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4

Dane są pobierane z adresu URL i przekazywane do kontrolera za pomocą mechanizmu wiązania modelu MVC. Kontroler pakuje dane do słownika ViewData i przekazuje ten obiekt do widoku. Następnie widok renderuje dane jako HTML w przeglądarce.

Privacy widok przedstawiający etykietę powitalną i frazę Hello Rick pokazaną cztery razy

W poprzednim przykładzie użyto słownika ViewData, aby przekazać dane z kontrolera do widoku. W dalszej części samouczka model widoku jest używany do przekazywania danych z kontrolera do widoku. Podejście modelu widoku do przekazywania danych jest preferowane w przypadku podejścia do słownika ViewData .

W następnym samouczku zostanie utworzona baza danych o filmach.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To w przejrzysty sposób enkapsuluje proces generowania odpowiedzi HTML dla klienta.

Szablony widoków są tworzone przy użyciu polecenia Razor. szablony widoków oparte na Razor:

  • Mieć rozszerzenie pliku .cshtml.
  • Zapewnij elegancki sposób tworzenia danych wyjściowych HTML za pomocą języka C#.

Index Obecnie metoda zwraca ciąg z komunikatem w klasie kontrolera. HelloWorldController W klasie zastąp metodę Index następującym kodem:

public IActionResult Index()
{
    return View();
}

Powyższy kod:

  • Wywołuje metodę View kontrolera.
  • Używa szablonu widoku do generowania odpowiedzi HTML.

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład metoda akcji Index w powyższym kodzie.
  • Zazwyczaj zwracaj obiekt IActionResult lub klasę pochodną od ActionResult, a nie typ taki jak string.

Dodawanie widoku

Kliknij prawym przyciskiem myszy folder Views , a następnie dodaj > nowy folder i nadaj nazwę folderowi HelloWorld.

Kliknij prawym przyciskiem myszy folder Views/HelloWorld, a następnie dodaj >nowy element.

W oknie dialogowym Dodawanie nowego elementu wybierz pozycję Pokaż wszystkie szablony.

W oknie dialogowym Dodawanie nowego elementu — MvcMovie:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybierz Razor Widok — Pusty
  • Zachowaj wartość pola Nazwa, Index.cshtml.
  • Wybierz Dodaj

Okno dialogowe Dodawanie nowego elementu

Zastąp zawartość Views/HelloWorld/Index.cshtmlRazor pliku widoku następującymi elementami:

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

Przejdź do https://localhost:{PORT}/HelloWorld:

  • Metoda Index w HelloWorldController uruchomiła instrukcję return View();, która określała, że metoda powinna użyć pliku szablonu widoku do wygenerowania odpowiedzi w przeglądarce.

  • Nie określono nazwy pliku szablonu widoku, więc domyślnie MVC używa domyślnego pliku widoku. Gdy nazwa pliku widoku nie jest określona, zwracany jest widok domyślny. Widok domyślny ma taką samą nazwę jak metoda akcji w Index tym przykładzie. Szablon widoku /Views/HelloWorld/Index.cshtml jest używany.

  • Na poniższej ilustracji przedstawiono ciąg "Hello from our View Template!" (Witaj z naszego szablonu widoku) zakodowany w widoku:

    Okno przeglądarki

Zmienianie widoków i stron układu

Wybierz łącza menu MvcFilm, Homei Privacy. Każda strona zawiera ten sam układ menu. Układ menu jest implementowany w Views/Shared/_Layout.cshtml pliku.

Otwórz plik Views/Shared/_Layout.cshtml.

Szablony układów umożliwiają:

  • Określanie układu kontenera HTML witryny w jednym miejscu.
  • Stosowanie układu kontenera HTML na wielu stronach w witrynie.

Znajdź wiersz @RenderBody(). RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie strony właściwe dla danego widoku, które tworzysz, osadzone w stronie układu. Jeśli na przykład klikniesz link Privacy, widok Views/Home/Privacy.cshtml zostanie wyrenderowany wewnątrz metody RenderBody.

Zastąp zawartość Views/Shared/_Layout.cshtml pliku następującym znacznikiem. Zmiany są wyróżnione:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie App</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="Movies" asp-action="Index">Movie App</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2023 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

Powyższe oznaczenie wprowadziło następujące zmiany:

  • Trzy wystąpienia w zakresie od MvcMovie do Movie App.
  • Element zakotwiczenia <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> do <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>.

W poprzednim kodzie znacznika pominięto asp-area=""atrybut pomocnika tagów Anchor oraz jego wartość, ponieważ ta aplikacja nie używa Areas.

Uwaga: Movies kontroler nie został zaimplementowany. W tym momencie Movie App łącze nie działa.

Zapisz zmiany i wybierz łącze Privacy. Zwróć uwagę, że tytuł na karcie przeglądarki wyświetla Privacy Polityka - Movie App zamiast Privacy Polityka - MvcMovie

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst kotwicy są wyświetlane jako Movie App. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Przejrzyj plik Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml dołącza plik Views/Shared/_Layout.cshtml do każdego widoku. Właściwość Layout może służyć do ustawiania innego widoku układu lub ustawiania go na null wartość , aby żaden plik układu nie był używany.

Views/HelloWorld/Index.cshtml Otwórz plik widoku.

Zmień tytuł i element <h2>, jak wyróżniono poniżej:

@{
    ViewData["Title"] = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

Tytuł i <h2> element są nieco inne, więc jest jasne, która część kodu zmienia ekran.

ViewData["Title"] = "Movie List"; w powyższym kodzie ustawia właściwość Title słownika ViewData na „Lista filmów”. Właściwość Title jest używana w elemecie <title> HTML na stronie układu:

<title>@ViewData["Title"] - Movie App</title>

Zapisz zmiany i przejdź do https://localhost:{PORT}/HelloWorld.

Zwróć uwagę, że zmieniono następujące elementy:

  • Tytuł przeglądarki.
  • Nagłówek podstawowy.
  • Nagłówki pomocnicze.

Jeśli w przeglądarce nie ma żadnych zmian, może to być buforowana zawartość, która jest przeglądana. Naciśnij Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony przy użyciu elementu ViewData["Title"], który ustawiamy w szablonie widoku Index.cshtml, oraz dodatkowego ciągu „- Movie App” dodanego w pliku layoutu.

Zawartość szablonu Index.cshtml widoku jest scalona z szablonem Views/Shared/_Layout.cshtml widoku. Pojedyncza odpowiedź HTML jest wysyłana do przeglądarki. Szablony układów ułatwiają wprowadzanie zmian, które mają zastosowanie na wszystkich stronach w aplikacji. Aby dowiedzieć się więcej, zobacz Układ.

Widok listy filmów

Mały fragment „danych”, komunikat „Hello from our View Template!”, jest jednak wpisany na stałe w kodzie. Aplikacja MVC ma jeszcze "V" (widok), "C" (kontroler), ale nie "M" (model).

Przekazywanie danych z kontrolera do widoku

Akcje kontrolera są wywoływane w odpowiedzi na przychodzące żądanie adresu URL. Klasa kontrolera to miejsce, w którym jest napisany kod, który obsługuje przychodzące żądania przeglądarki. Kontroler pobiera dane ze źródła danych i decyduje, jakiego typu odpowiedź ma być wysyłana z powrotem do przeglądarki. Szablony widoków mogą być używane z poziomu kontrolera do generowania i formatowania odpowiedzi HTML dla przeglądarki.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych, aby szablon widoku mógł wyrenderować odpowiedź.

Szablony widoku nie powinny:

  • Wykonaj logikę biznesową
  • Bezpośrednia interakcja z bazą danych.

Szablon widoku powinien działać tylko z danymi dostarczonymi przez kontroler. Utrzymanie tego "rozdzielenia problemów" pomaga zachować kod:

  • Czysty.
  • Testowalny.
  • Łatwy w utrzymaniu.

Obecnie metoda Welcome w klasie HelloWorldController przyjmuje parametr name i parametr ID, a następnie wypisuje wartości bezpośrednio w przeglądarce.

Zamiast renderować tę odpowiedź jako ciąg znaków w kontrolerze, zmień kontroler tak, aby zamiast tego używał szablonu widoku. Szablon widoku generuje dynamiczną odpowiedź, co oznacza, że odpowiednie dane muszą zostać przekazane z kontrolera do widoku w celu wygenerowania odpowiedzi. W tym celu kontroler umieszcza dane dynamiczne (parametry), których potrzebuje szablon widoku w słowniku ViewData . Następnie szablon widoku może uzyskiwać dostęp do danych dynamicznych.

W pliku HelloWorldController.cs zmień metodę Welcome, aby dodać do słownika ViewData wartości Message i NumTimes.

Słownik ViewData jest obiektem dynamicznym, co oznacza, że można użyć dowolnego typu. Obiekt ViewData nie ma zdefiniowanych właściwości, dopóki coś nie zostanie dodane. System powiązania modelu MVC automatycznie mapuje nazwane parametry name i numTimes z ciągu zapytania na parametry w metodzie . Cały HelloWorldController:

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers;

public class HelloWorldController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
    public IActionResult Welcome(string name, int numTimes = 1)
    {
        ViewData["Message"] = "Hello " + name;
        ViewData["NumTimes"] = numTimes;
        return View();
    }
}

Obiekt słownika ViewData zawiera dane, które zostaną przekazane do widoku.

Utwórz szablon widoku powitalnego o nazwie Views/HelloWorld/Welcome.cshtml.

Utworzysz pętlę w szablonie Welcome.cshtml widoku, który wyświetla komunikat "Hello" NumTimes. Zastąp zawartość Views/HelloWorld/Welcome.cshtml pliku następującym kodem:

@{
    ViewData["Title"] = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < (int)ViewData["NumTimes"]!; i++)
    {
        <li>@ViewData["Message"]</li>
    }
</ul>

Zapisz zmiany i przejdź do następującego adresu URL:

https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4

Dane są pobierane z adresu URL i przekazywane do kontrolera za pomocą mechanizmu wiązania modelu MVC. Kontroler pakuje dane do słownika ViewData i przekazuje ten obiekt do widoku. Następnie widok renderuje dane jako HTML w przeglądarce.

Privacy widok przedstawiający etykietę powitalną i frazę Hello Rick pokazaną cztery razy

W poprzednim przykładzie użyto słownika ViewData, aby przekazać dane z kontrolera do widoku. W dalszej części samouczka model widoku jest używany do przekazywania danych z kontrolera do widoku. Podejście modelu widoku do przekazywania danych jest preferowane w przypadku podejścia do słownika ViewData .

W następnym samouczku zostanie utworzona baza danych o filmach.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To w przejrzysty sposób enkapsuluje proces generowania odpowiedzi HTML dla klienta.

Szablony widoków są tworzone przy użyciu polecenia Razor. szablony widoków oparte na Razor:

  • Mieć rozszerzenie pliku .cshtml.
  • Zapewnij elegancki sposób tworzenia danych wyjściowych HTML za pomocą języka C#.

Index Obecnie metoda zwraca ciąg z komunikatem w klasie kontrolera. HelloWorldController W klasie zastąp metodę Index następującym kodem:

public IActionResult Index()
{
    return View();
}

Powyższy kod:

  • Wywołuje metodę View kontrolera.
  • Używa szablonu widoku do generowania odpowiedzi HTML.

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład metoda akcji Index w powyższym kodzie.
  • Zazwyczaj zwracaj obiekt IActionResult lub klasę pochodną od ActionResult, a nie typ taki jak string.

Dodawanie widoku

Kliknij prawym przyciskiem myszy folder Views , a następnie dodaj > nowy folder i nadaj nazwę folderowi HelloWorld.

Kliknij prawym przyciskiem myszy folder Views/HelloWorld, a następnie dodaj >nowy element.

W oknie dialogowym Dodawanie nowego elementu — MvcMovie:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybierz Razor Widok — Pusty
  • Zachowaj wartość pola Nazwa, Index.cshtml.
  • Wybierz Dodaj

Okno dialogowe Dodawanie nowego elementu

Zastąp zawartość Views/HelloWorld/Index.cshtmlRazor pliku widoku następującymi elementami:

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

Przejdź do https://localhost:{PORT}/HelloWorld:

  • Metoda Index w HelloWorldController uruchomiła instrukcję return View();, która określała, że metoda powinna użyć pliku szablonu widoku do wygenerowania odpowiedzi w przeglądarce.

  • Nie określono nazwy pliku szablonu widoku, więc domyślnie MVC używa domyślnego pliku widoku. Gdy nazwa pliku widoku nie jest określona, zwracany jest widok domyślny. Widok domyślny ma taką samą nazwę jak metoda akcji w Index tym przykładzie. Szablon widoku /Views/HelloWorld/Index.cshtml jest używany.

  • Na poniższej ilustracji przedstawiono ciąg "Hello from our View Template!" (Witaj z naszego szablonu widoku) zakodowany w widoku:

    Okno przeglądarki

Zmienianie widoków i stron układu

Wybierz łącza menu MvcFilm, Homei Privacy. Każda strona zawiera ten sam układ menu. Układ menu jest implementowany w Views/Shared/_Layout.cshtml pliku.

Otwórz plik Views/Shared/_Layout.cshtml.

Szablony układów umożliwiają:

  • Określanie układu kontenera HTML witryny w jednym miejscu.
  • Stosowanie układu kontenera HTML na wielu stronach w witrynie.

Znajdź wiersz @RenderBody(). RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie strony właściwe dla danego widoku, które tworzysz, osadzone w stronie układu. Jeśli na przykład klikniesz link Privacy, widok Views/Home/Privacy.cshtml zostanie wyrenderowany wewnątrz metody RenderBody.

Zastąp zawartość Views/Shared/_Layout.cshtml pliku następującym znacznikiem. Zmiany są wyróżnione:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie App</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="Movies" asp-action="Index">Movie App</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2022 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

Powyższe oznaczenie wprowadziło następujące zmiany:

  • Trzy wystąpienia w zakresie od MvcMovie do Movie App.
  • Element zakotwiczenia <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> do <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>.

W poprzednim kodzie znacznika pominięto asp-area=""atrybut pomocnika tagów Anchor oraz jego wartość, ponieważ ta aplikacja nie używa Areas.

Uwaga: Movies kontroler nie został zaimplementowany. W tym momencie Movie App łącze nie działa.

Zapisz zmiany i wybierz łącze Privacy. Zwróć uwagę, że tytuł na karcie przeglądarki wyświetla Privacy Polityka - Movie App zamiast Privacy Polityka - MvcMovie

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst kotwicy są wyświetlane jako Movie App. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Przejrzyj plik Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml dołącza plik Views/Shared/_Layout.cshtml do każdego widoku. Właściwość Layout może służyć do ustawiania innego widoku układu lub ustawiania go na null wartość , aby żaden plik układu nie był używany.

Views/HelloWorld/Index.cshtml Otwórz plik widoku.

Zmień tytuł i element <h2>, jak wyróżniono poniżej:

@{
    ViewData["Title"] = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

Tytuł i <h2> element są nieco inne, więc jest jasne, która część kodu zmienia ekran.

ViewData["Title"] = "Movie List"; w powyższym kodzie ustawia właściwość Title słownika ViewData na „Lista filmów”. Właściwość Title jest używana w elemecie <title> HTML na stronie układu:

<title>@ViewData["Title"] - Movie App</title>

Zapisz zmiany i przejdź do https://localhost:{PORT}/HelloWorld.

Zwróć uwagę, że zmieniono następujące elementy:

  • Tytuł przeglądarki.
  • Nagłówek podstawowy.
  • Nagłówki pomocnicze.

Jeśli w przeglądarce nie ma żadnych zmian, może to być buforowana zawartość, która jest przeglądana. Naciśnij Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony przy użyciu elementu ViewData["Title"], który ustawiamy w szablonie widoku Index.cshtml, oraz dodatkowego ciągu „- Movie App” dodanego w pliku layoutu.

Zawartość szablonu Index.cshtml widoku jest scalona z szablonem Views/Shared/_Layout.cshtml widoku. Pojedyncza odpowiedź HTML jest wysyłana do przeglądarki. Szablony układów ułatwiają wprowadzanie zmian, które mają zastosowanie na wszystkich stronach w aplikacji. Aby dowiedzieć się więcej, zobacz Układ.

Widok listy filmów

Mały fragment „danych”, komunikat „Hello from our View Template!”, jest jednak wpisany na stałe w kodzie. Aplikacja MVC ma jeszcze "V" (widok), "C" (kontroler), ale nie "M" (model).

Przekazywanie danych z kontrolera do widoku

Akcje kontrolera są wywoływane w odpowiedzi na przychodzące żądanie adresu URL. Klasa kontrolera to miejsce, w którym jest napisany kod, który obsługuje przychodzące żądania przeglądarki. Kontroler pobiera dane ze źródła danych i decyduje, jakiego typu odpowiedź ma być wysyłana z powrotem do przeglądarki. Szablony widoków mogą być używane z poziomu kontrolera do generowania i formatowania odpowiedzi HTML dla przeglądarki.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych, aby szablon widoku mógł wyrenderować odpowiedź.

Szablony widoku nie powinny:

  • Wykonaj logikę biznesową
  • Bezpośrednia interakcja z bazą danych.

Szablon widoku powinien działać tylko z danymi dostarczonymi przez kontroler. Utrzymanie tego "rozdzielenia problemów" pomaga zachować kod:

  • Czysty.
  • Testowalny.
  • Łatwy w utrzymaniu.

Obecnie metoda Welcome w klasie HelloWorldController przyjmuje parametr name i parametr ID, a następnie wypisuje wartości bezpośrednio w przeglądarce.

Zamiast renderować tę odpowiedź jako ciąg znaków w kontrolerze, zmień kontroler tak, aby zamiast tego używał szablonu widoku. Szablon widoku generuje dynamiczną odpowiedź, co oznacza, że odpowiednie dane muszą zostać przekazane z kontrolera do widoku w celu wygenerowania odpowiedzi. W tym celu kontroler umieszcza dane dynamiczne (parametry), których potrzebuje szablon widoku w słowniku ViewData . Następnie szablon widoku może uzyskiwać dostęp do danych dynamicznych.

W pliku HelloWorldController.cs zmień metodę Welcome, aby dodać do słownika ViewData wartości Message i NumTimes.

Słownik ViewData jest obiektem dynamicznym, co oznacza, że można użyć dowolnego typu. Obiekt ViewData nie ma zdefiniowanych właściwości, dopóki coś nie zostanie dodane. System powiązania modelu MVC automatycznie mapuje nazwane parametry name i numTimes z ciągu zapytania na parametry w metodzie . Cały HelloWorldController:

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers;

public class HelloWorldController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
    public IActionResult Welcome(string name, int numTimes = 1)
    {
        ViewData["Message"] = "Hello " + name;
        ViewData["NumTimes"] = numTimes;
        return View();
    }
}

Obiekt słownika ViewData zawiera dane, które zostaną przekazane do widoku.

Utwórz szablon widoku powitalnego o nazwie Views/HelloWorld/Welcome.cshtml.

Utworzysz pętlę w szablonie Welcome.cshtml widoku, który wyświetla komunikat "Hello" NumTimes. Zastąp zawartość Views/HelloWorld/Welcome.cshtml pliku następującym kodem:

@{
    ViewData["Title"] = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < (int)ViewData["NumTimes"]!; i++)
    {
        <li>@ViewData["Message"]</li>
    }
</ul>

Zapisz zmiany i przejdź do następującego adresu URL:

https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4

Dane są pobierane z adresu URL i przekazywane do kontrolera za pomocą mechanizmu wiązania modelu MVC. Kontroler pakuje dane do słownika ViewData i przekazuje ten obiekt do widoku. Następnie widok renderuje dane jako HTML w przeglądarce.

Privacy widok przedstawiający etykietę powitalną i frazę Hello Rick pokazaną cztery razy

W poprzednim przykładzie użyto słownika ViewData, aby przekazać dane z kontrolera do widoku. W dalszej części samouczka model widoku jest używany do przekazywania danych z kontrolera do widoku. Podejście modelu widoku do przekazywania danych jest preferowane w przypadku podejścia do słownika ViewData .

W następnym samouczku zostanie utworzona baza danych o filmach.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To w przejrzysty sposób enkapsuluje proces generowania odpowiedzi HTML dla klienta.

Szablony widoków są tworzone przy użyciu polecenia Razor. szablony widoków oparte na Razor:

  • Mieć rozszerzenie pliku .cshtml.
  • Zapewnij elegancki sposób tworzenia danych wyjściowych HTML za pomocą języka C#.

Index Obecnie metoda zwraca ciąg z komunikatem w klasie kontrolera. HelloWorldController W klasie zastąp metodę Index następującym kodem:

public IActionResult Index()
{
    return View();
}

Powyższy kod:

  • Wywołuje metodę View kontrolera.
  • Używa szablonu widoku do generowania odpowiedzi HTML.

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład metoda akcji Index w powyższym kodzie.
  • Zazwyczaj zwracaj obiekt IActionResult lub klasę pochodną od ActionResult, a nie typ taki jak string.

Dodawanie widoku

Kliknij prawym przyciskiem myszy folder Views , a następnie dodaj > nowy folder i nadaj nazwę folderowi HelloWorld.

Kliknij prawym przyciskiem myszy folder Views/HelloWorld, a następnie dodaj >nowy element.

W oknie dialogowym Dodawanie nowego elementu — MvcMovie:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybierz Razor Widok — Pusty
  • Zachowaj wartość pola Nazwa, Index.cshtml.
  • Wybierz Dodaj

Okno dialogowe Dodawanie nowego elementu

Zastąp zawartość Views/HelloWorld/Index.cshtmlRazor pliku widoku następującymi elementami:

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

Przejdź do https://localhost:{PORT}/HelloWorld:

  • Metoda Index w HelloWorldController uruchomiła instrukcję return View();, która określała, że metoda powinna użyć pliku szablonu widoku do wygenerowania odpowiedzi w przeglądarce.

  • Nie określono nazwy pliku szablonu widoku, więc domyślnie MVC używa domyślnego pliku widoku. Gdy nazwa pliku widoku nie jest określona, zwracany jest widok domyślny. Widok domyślny ma taką samą nazwę jak metoda akcji w Index tym przykładzie. Szablon widoku /Views/HelloWorld/Index.cshtml jest używany.

  • Na poniższej ilustracji przedstawiono ciąg "Hello from our View Template!" (Witaj z naszego szablonu widoku) zakodowany w widoku:

    Okno przeglądarki

Zmienianie widoków i stron układu

Wybierz łącza menu MvcFilm, Homei Privacy. Każda strona zawiera ten sam układ menu. Układ menu jest implementowany w Views/Shared/_Layout.cshtml pliku.

Otwórz plik Views/Shared/_Layout.cshtml.

Szablony układów umożliwiają:

  • Określanie układu kontenera HTML witryny w jednym miejscu.
  • Stosowanie układu kontenera HTML na wielu stronach w witrynie.

Znajdź wiersz @RenderBody(). RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie strony właściwe dla danego widoku, które tworzysz, osadzone w stronie układu. Jeśli na przykład klikniesz link Privacy, widok Views/Home/Privacy.cshtml zostanie wyrenderowany wewnątrz metody RenderBody.

Zastąp zawartość Views/Shared/_Layout.cshtml pliku następującym znacznikiem. Zmiany są wyróżnione:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie App</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="Movies" asp-action="Index">Movie App</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2021 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

Powyższe oznaczenie wprowadziło następujące zmiany:

  • Trzy wystąpienia w zakresie od MvcMovie do Movie App.
  • Element zakotwiczenia <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> do <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>.

W poprzednim kodzie znacznika pominięto asp-area=""atrybut pomocnika tagów Anchor oraz jego wartość, ponieważ ta aplikacja nie używa Areas.

Uwaga: Movies kontroler nie został zaimplementowany. W tym momencie Movie App łącze nie działa.

Zapisz zmiany i wybierz łącze Privacy. Zwróć uwagę, że tytuł na karcie przeglądarki wyświetla Privacy Polityka - Movie App zamiast Privacy Polityka - MvcMovie

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst kotwicy są wyświetlane jako Movie App. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Przejrzyj plik Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml dołącza plik Views/Shared/_Layout.cshtml do każdego widoku. Właściwość Layout może służyć do ustawiania innego widoku układu lub ustawiania go na null wartość , aby żaden plik układu nie był używany.

Views/HelloWorld/Index.cshtml Otwórz plik widoku.

Zmień tytuł i element <h2>, jak wyróżniono poniżej:

@{
    ViewData["Title"] = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

Tytuł i <h2> element są nieco inne, więc jest jasne, która część kodu zmienia ekran.

ViewData["Title"] = "Movie List"; w powyższym kodzie ustawia właściwość Title słownika ViewData na „Lista filmów”. Właściwość Title jest używana w elemecie <title> HTML na stronie układu:

<title>@ViewData["Title"] - Movie App</title>

Zapisz zmiany i przejdź do https://localhost:{PORT}/HelloWorld.

Zwróć uwagę, że zmieniono następujące elementy:

  • Tytuł przeglądarki.
  • Nagłówek podstawowy.
  • Nagłówki pomocnicze.

Jeśli w przeglądarce nie ma żadnych zmian, może to być buforowana zawartość, która jest przeglądana. Naciśnij Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony przy użyciu elementu ViewData["Title"], który ustawiamy w szablonie widoku Index.cshtml, oraz dodatkowego ciągu „- Movie App” dodanego w pliku layoutu.

Zawartość szablonu Index.cshtml widoku jest scalona z szablonem Views/Shared/_Layout.cshtml widoku. Pojedyncza odpowiedź HTML jest wysyłana do przeglądarki. Szablony układów ułatwiają wprowadzanie zmian, które mają zastosowanie na wszystkich stronach w aplikacji. Aby dowiedzieć się więcej, zobacz Układ.

Widok listy filmów

Mały fragment „danych”, komunikat „Hello from our View Template!”, jest jednak wpisany na stałe w kodzie. Aplikacja MVC ma jeszcze "V" (widok), "C" (kontroler), ale nie "M" (model).

Przekazywanie danych z kontrolera do widoku

Akcje kontrolera są wywoływane w odpowiedzi na przychodzące żądanie adresu URL. Klasa kontrolera to miejsce, w którym jest napisany kod, który obsługuje przychodzące żądania przeglądarki. Kontroler pobiera dane ze źródła danych i decyduje, jakiego typu odpowiedź ma być wysyłana z powrotem do przeglądarki. Szablony widoków mogą być używane z poziomu kontrolera do generowania i formatowania odpowiedzi HTML dla przeglądarki.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych, aby szablon widoku mógł wyrenderować odpowiedź.

Szablony widoku nie powinny:

  • Wykonaj logikę biznesową
  • Bezpośrednia interakcja z bazą danych.

Szablon widoku powinien działać tylko z danymi dostarczonymi przez kontroler. Utrzymanie tego "rozdzielenia problemów" pomaga zachować kod:

  • Czysty.
  • Testowalny.
  • Łatwy w utrzymaniu.

Obecnie metoda Welcome w klasie HelloWorldController przyjmuje parametr name i parametr ID, a następnie wypisuje wartości bezpośrednio w przeglądarce.

Zamiast renderować tę odpowiedź jako ciąg znaków w kontrolerze, zmień kontroler tak, aby zamiast tego używał szablonu widoku. Szablon widoku generuje dynamiczną odpowiedź, co oznacza, że odpowiednie dane muszą zostać przekazane z kontrolera do widoku w celu wygenerowania odpowiedzi. W tym celu kontroler umieszcza dane dynamiczne (parametry), których potrzebuje szablon widoku w słowniku ViewData . Następnie szablon widoku może uzyskiwać dostęp do danych dynamicznych.

W pliku HelloWorldController.cs zmień metodę Welcome, aby dodać do słownika ViewData wartości Message i NumTimes.

Słownik ViewData jest obiektem dynamicznym, co oznacza, że można użyć dowolnego typu. Obiekt ViewData nie ma zdefiniowanych właściwości, dopóki coś nie zostanie dodane. System powiązania modelu MVC automatycznie mapuje nazwane parametry name i numTimes z ciągu zapytania na parametry w metodzie . Cały HelloWorldController:

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers
{
    public class HelloWorldController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Welcome(string name, int numTimes = 1)
        {
            ViewData["Message"] = "Hello " + name;
            ViewData["NumTimes"] = numTimes;

            return View();
        }
    }
}

Obiekt słownika ViewData zawiera dane, które zostaną przekazane do widoku.

Utwórz szablon widoku powitalnego o nazwie Views/HelloWorld/Welcome.cshtml.

Utworzysz pętlę w szablonie Welcome.cshtml widoku, który wyświetla komunikat "Hello" NumTimes. Zastąp zawartość Views/HelloWorld/Welcome.cshtml pliku następującym kodem:

@{
    ViewData["Title"] = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < (int)ViewData["NumTimes"]!; i++)
    {
        <li>@ViewData["Message"]</li>
    }
</ul>

Zapisz zmiany i przejdź do następującego adresu URL:

https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4

Dane są pobierane z adresu URL i przekazywane do kontrolera za pomocą mechanizmu wiązania modelu MVC. Kontroler pakuje dane do słownika ViewData i przekazuje ten obiekt do widoku. Następnie widok renderuje dane jako HTML w przeglądarce.

Privacy widok przedstawiający etykietę powitalną i frazę Hello Rick pokazaną cztery razy

W poprzednim przykładzie użyto słownika ViewData, aby przekazać dane z kontrolera do widoku. W dalszej części samouczka model widoku jest używany do przekazywania danych z kontrolera do widoku. Podejście modelu widoku do przekazywania danych jest preferowane w przypadku podejścia do słownika ViewData .

W następnym samouczku zostanie utworzona baza danych o filmach.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To w przejrzysty sposób enkapsuluje proces generowania odpowiedzi HTML dla klienta.

Szablony widoków są tworzone przy użyciu polecenia Razor. szablony widoków oparte na Razor:

  • Mieć rozszerzenie pliku .cshtml.
  • Zapewnij elegancki sposób tworzenia danych wyjściowych HTML za pomocą języka C#.

Index Obecnie metoda zwraca ciąg z komunikatem w klasie kontrolera. HelloWorldController W klasie zastąp metodę Index następującym kodem:

public IActionResult Index()
{
    return View();
}

Powyższy kod:

  • Wywołuje metodę View kontrolera.
  • Używa szablonu widoku do generowania odpowiedzi HTML.

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład metoda akcji Index w powyższym kodzie.
  • Zazwyczaj zwracaj obiekt IActionResult lub klasę pochodną od ActionResult, a nie typ taki jak string.

Dodawanie widoku

Kliknij prawym przyciskiem myszy folder Views , a następnie dodaj > nowy folder i nadaj nazwę folderowi HelloWorld.

Kliknij prawym przyciskiem myszy folder Views/HelloWorld, a następnie dodaj >nowy element.

W oknie dialogowym Dodawanie nowego elementu — MvcMovie:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybierz Razor Widok — Pusty
  • Zachowaj wartość pola Nazwa, Index.cshtml.
  • Wybierz Dodaj

Okno dialogowe Dodawanie nowego elementu

Zastąp zawartość Views/HelloWorld/Index.cshtmlRazor pliku widoku następującymi elementami:

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

Przejdź do https://localhost:{PORT}/HelloWorld:

  • Metoda Index w HelloWorldController uruchomiła instrukcję return View();, która określała, że metoda powinna użyć pliku szablonu widoku do wygenerowania odpowiedzi w przeglądarce.

  • Nie określono nazwy pliku szablonu widoku, więc domyślnie MVC używa domyślnego pliku widoku. Gdy nazwa pliku widoku nie jest określona, zwracany jest widok domyślny. Widok domyślny ma taką samą nazwę jak metoda akcji w Index tym przykładzie. Szablon widoku /Views/HelloWorld/Index.cshtml jest używany.

  • Na poniższej ilustracji przedstawiono ciąg "Hello from our View Template!" (Witaj z naszego szablonu widoku) zakodowany w widoku:

    Okno przeglądarki

Zmienianie widoków i stron układu

Wybierz łącza menu MvcFilm, Homei Privacy. Każda strona zawiera ten sam układ menu. Układ menu jest implementowany w Views/Shared/_Layout.cshtml pliku.

Otwórz plik Views/Shared/_Layout.cshtml.

Szablony układów umożliwiają:

  • Określanie układu kontenera HTML witryny w jednym miejscu.
  • Stosowanie układu kontenera HTML na wielu stronach w witrynie.

Znajdź wiersz @RenderBody(). RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie strony właściwe dla danego widoku, które tworzysz, osadzone w stronie układu. Jeśli na przykład klikniesz link Privacy, widok Views/Home/Privacy.cshtml zostanie wyrenderowany wewnątrz metody RenderBody.

Zastąp zawartość Views/Shared/_Layout.cshtml pliku następującym znacznikiem. Zmiany są wyróżnione:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie App</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2020 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

Powyższe oznaczenie wprowadziło następujące zmiany:

  • Trzy wystąpienia w zakresie od MvcMovie do Movie App.
  • Element zakotwiczenia <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> do <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>.

W poprzednim kodzie znacznika pominięto asp-area=""atrybut pomocnika tagów Anchor oraz jego wartość, ponieważ ta aplikacja nie używa Areas.

Uwaga: Movies kontroler nie został zaimplementowany. W tym momencie Movie App łącze nie działa.

Zapisz zmiany i wybierz łącze Privacy. Zwróć uwagę, że tytuł na karcie przeglądarki wyświetla Privacy Polityka - Movie App zamiast Privacy Polityka - MvcMovie

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst kotwicy są wyświetlane jako Movie App. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Przejrzyj plik Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml dołącza plik Views/Shared/_Layout.cshtml do każdego widoku. Właściwość Layout może służyć do ustawiania innego widoku układu lub ustawiania go na null wartość , aby żaden plik układu nie był używany.

Views/HelloWorld/Index.cshtml Otwórz plik widoku.

Zmień tytuł i element <h2>, jak wyróżniono poniżej:

@{
    ViewData["Title"] = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

Tytuł i <h2> element są nieco inne, więc jest jasne, która część kodu zmienia ekran.

ViewData["Title"] = "Movie List"; w powyższym kodzie ustawia właściwość Title słownika ViewData na „Lista filmów”. Właściwość Title jest używana w elemecie <title> HTML na stronie układu:

<title>@ViewData["Title"] - Movie App</title>

Zapisz zmiany i przejdź do https://localhost:{PORT}/HelloWorld.

Zwróć uwagę, że zmieniono następujące elementy:

  • Tytuł przeglądarki.
  • Nagłówek podstawowy.
  • Nagłówki pomocnicze.

Jeśli w przeglądarce nie ma żadnych zmian, może to być buforowana zawartość, która jest przeglądana. Naciśnij Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony przy użyciu elementu ViewData["Title"], który ustawiamy w szablonie widoku Index.cshtml, oraz dodatkowego ciągu „- Movie App” dodanego w pliku layoutu.

Zawartość szablonu Index.cshtml widoku jest scalona z szablonem Views/Shared/_Layout.cshtml widoku. Pojedyncza odpowiedź HTML jest wysyłana do przeglądarki. Szablony układów ułatwiają wprowadzanie zmian, które mają zastosowanie na wszystkich stronach w aplikacji. Aby dowiedzieć się więcej, zobacz Układ.

Widok listy filmów

Mały fragment „danych”, komunikat „Hello from our View Template!”, jest jednak wpisany na stałe w kodzie. Aplikacja MVC ma jeszcze "V" (widok), "C" (kontroler), ale nie "M" (model).

Przekazywanie danych z kontrolera do widoku

Akcje kontrolera są wywoływane w odpowiedzi na przychodzące żądanie adresu URL. Klasa kontrolera to miejsce, w którym jest napisany kod, który obsługuje przychodzące żądania przeglądarki. Kontroler pobiera dane ze źródła danych i decyduje, jakiego typu odpowiedź ma być wysyłana z powrotem do przeglądarki. Szablony widoków mogą być używane z poziomu kontrolera do generowania i formatowania odpowiedzi HTML dla przeglądarki.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych, aby szablon widoku mógł wyrenderować odpowiedź.

Szablony widoku nie powinny:

  • Wykonaj logikę biznesową
  • Bezpośrednia interakcja z bazą danych.

Szablon widoku powinien działać tylko z danymi dostarczonymi przez kontroler. Utrzymanie tego "rozdzielenia problemów" pomaga zachować kod:

  • Czysty.
  • Testowalny.
  • Łatwy w utrzymaniu.

Obecnie metoda Welcome w klasie HelloWorldController przyjmuje parametr name i parametr ID, a następnie wypisuje wartości bezpośrednio w przeglądarce.

Zamiast renderować tę odpowiedź jako ciąg znaków w kontrolerze, zmień kontroler tak, aby zamiast tego używał szablonu widoku. Szablon widoku generuje dynamiczną odpowiedź, co oznacza, że odpowiednie dane muszą zostać przekazane z kontrolera do widoku w celu wygenerowania odpowiedzi. W tym celu kontroler umieszcza dane dynamiczne (parametry), których potrzebuje szablon widoku w słowniku ViewData . Następnie szablon widoku może uzyskiwać dostęp do danych dynamicznych.

W pliku HelloWorldController.cs zmień metodę Welcome, aby dodać do słownika ViewData wartości Message i NumTimes.

Słownik ViewData jest obiektem dynamicznym, co oznacza, że można użyć dowolnego typu. Obiekt ViewData nie ma zdefiniowanych właściwości, dopóki coś nie zostanie dodane. System powiązania modelu MVC automatycznie mapuje nazwane parametry name i numTimes z ciągu zapytania na parametry w metodzie . Cały HelloWorldController:

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers
{
    public class HelloWorldController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Welcome(string name, int numTimes = 1)
        {
            ViewData["Message"] = "Hello " + name;
            ViewData["NumTimes"] = numTimes;

            return View();
        }
    }
}

Obiekt słownika ViewData zawiera dane, które zostaną przekazane do widoku.

Utwórz szablon widoku powitalnego o nazwie Views/HelloWorld/Welcome.cshtml.

Utworzysz pętlę w szablonie Welcome.cshtml widoku, który wyświetla komunikat "Hello" NumTimes. Zastąp zawartość Views/HelloWorld/Welcome.cshtml pliku następującym kodem:

@{
    ViewData["Title"] = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < (int)ViewData["NumTimes"]; i++)
    {
        <li>@ViewData["Message"]</li>
    }
</ul>

Zapisz zmiany i przejdź do następującego adresu URL:

https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4

Dane są pobierane z adresu URL i przekazywane do kontrolera za pomocą mechanizmu wiązania modelu MVC. Kontroler pakuje dane do słownika ViewData i przekazuje ten obiekt do widoku. Następnie widok renderuje dane jako HTML w przeglądarce.

Privacy widok przedstawiający etykietę powitalną i frazę Hello Rick pokazaną cztery razy

W poprzednim przykładzie użyto słownika ViewData, aby przekazać dane z kontrolera do widoku. W dalszej części samouczka model widoku jest używany do przekazywania danych z kontrolera do widoku. Podejście modelu widoku do przekazywania danych jest preferowane w przypadku podejścia do słownika ViewData .

W następnym samouczku zostanie utworzona baza danych o filmach.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To w przejrzysty sposób enkapsuluje proces generowania odpowiedzi HTML dla klienta.

Szablony widoków są tworzone przy użyciu polecenia Razor. szablony widoków oparte na Razor:

  • Mieć rozszerzenie pliku .cshtml.
  • Zapewnij elegancki sposób tworzenia danych wyjściowych HTML za pomocą języka C#.

Index Obecnie metoda zwraca ciąg z komunikatem w klasie kontrolera. HelloWorldController W klasie zastąp metodę Index następującym kodem:

public IActionResult Index()
{
    return View();
}

Powyższy kod:

  • Wywołuje metodę View kontrolera.
  • Używa szablonu widoku do generowania odpowiedzi HTML.

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład metoda akcji Index w powyższym kodzie.
  • Zazwyczaj zwracaj obiekt IActionResult lub klasę pochodną od ActionResult, a nie typ taki jak string.

Dodawanie widoku

Kliknij prawym przyciskiem myszy folder Views , a następnie dodaj > nowy folder i nadaj nazwę folderowi HelloWorld.

Kliknij prawym przyciskiem myszy folder Views/HelloWorld, a następnie dodaj >nowy element.

W oknie dialogowym Dodawanie nowego elementu — MvcMovie:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybierz Razor Widok — Pusty
  • Zachowaj wartość pola Nazwa, Index.cshtml.
  • Wybierz Dodaj

Okno dialogowe Dodawanie nowego elementu

Zastąp zawartość Views/HelloWorld/Index.cshtmlRazor pliku widoku następującymi elementami:

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

Przejdź do https://localhost:{PORT}/HelloWorld:

  • Metoda Index w HelloWorldController uruchomiła instrukcję return View();, która określała, że metoda powinna użyć pliku szablonu widoku do wygenerowania odpowiedzi w przeglądarce.

  • Nie określono nazwy pliku szablonu widoku, więc domyślnie MVC używa domyślnego pliku widoku. Gdy nazwa pliku widoku nie jest określona, zwracany jest widok domyślny. Widok domyślny ma taką samą nazwę jak metoda akcji w Index tym przykładzie. Szablon widoku /Views/HelloWorld/Index.cshtml jest używany.

  • Na poniższej ilustracji przedstawiono ciąg "Hello from our View Template!" (Witaj z naszego szablonu widoku) zakodowany w widoku:

    Okno przeglądarki

Zmienianie widoków i stron układu

Wybierz łącza menu MvcFilm, Homei Privacy. Każda strona zawiera ten sam układ menu. Układ menu jest implementowany w Views/Shared/_Layout.cshtml pliku.

Otwórz plik Views/Shared/_Layout.cshtml.

Szablony układów umożliwiają:

  • Określanie układu kontenera HTML witryny w jednym miejscu.
  • Stosowanie układu kontenera HTML na wielu stronach w witrynie.

Znajdź wiersz @RenderBody(). RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie strony właściwe dla danego widoku, które tworzysz, osadzone w stronie układu. Jeśli na przykład klikniesz link Privacy, widok Views/Home/Privacy.cshtml zostanie wyrenderowany wewnątrz metody RenderBody.

Zastąp zawartość Views/Shared/_Layout.cshtml pliku następującym znacznikiem. Zmiany są wyróżnione:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie App</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2020 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @RenderSection("Scripts", required: false)
</body>
</html>

Powyższe oznaczenie wprowadziło następujące zmiany:

  • Trzy wystąpienia w zakresie od MvcMovie do Movie App.
  • Element zakotwiczenia <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> do <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>.

W poprzednim kodzie znacznika pominięto asp-area=""atrybut pomocnika tagów Anchor oraz jego wartość, ponieważ ta aplikacja nie używa Areas.

Uwaga: Movies kontroler nie został zaimplementowany. W tym momencie Movie App łącze nie działa.

Zapisz zmiany i wybierz łącze Privacy. Zwróć uwagę, że tytuł na karcie przeglądarki wyświetla Privacy Polityka - Movie App zamiast Privacy Polityka - MvcMovie

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst kotwicy są wyświetlane jako Movie App. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Przejrzyj plik Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml dołącza plik Views/Shared/_Layout.cshtml do każdego widoku. Właściwość Layout może służyć do ustawiania innego widoku układu lub ustawiania go na null wartość , aby żaden plik układu nie był używany.

Views/HelloWorld/Index.cshtml Otwórz plik widoku.

Zmień tytuł i element <h2>, jak wyróżniono poniżej:

@{
    ViewData["Title"] = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

Tytuł i <h2> element są nieco inne, więc jest jasne, która część kodu zmienia ekran.

ViewData["Title"] = "Movie List"; w powyższym kodzie ustawia właściwość Title słownika ViewData na „Lista filmów”. Właściwość Title jest używana w elemecie <title> HTML na stronie układu:

<title>@ViewData["Title"] - Movie App</title>

Zapisz zmiany i przejdź do https://localhost:{PORT}/HelloWorld.

Zwróć uwagę, że zmieniono następujące elementy:

  • Tytuł przeglądarki.
  • Nagłówek podstawowy.
  • Nagłówki pomocnicze.

Jeśli w przeglądarce nie ma żadnych zmian, może to być buforowana zawartość, która jest przeglądana. Naciśnij Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony przy użyciu elementu ViewData["Title"], który ustawiamy w szablonie widoku Index.cshtml, oraz dodatkowego ciągu „- Movie App” dodanego w pliku layoutu.

Zawartość szablonu Index.cshtml widoku jest scalona z szablonem Views/Shared/_Layout.cshtml widoku. Pojedyncza odpowiedź HTML jest wysyłana do przeglądarki. Szablony układów ułatwiają wprowadzanie zmian, które mają zastosowanie na wszystkich stronach w aplikacji. Aby dowiedzieć się więcej, zobacz Układ.

Widok listy filmów

Mały fragment „danych”, komunikat „Hello from our View Template!”, jest jednak wpisany na stałe w kodzie. Aplikacja MVC ma jeszcze "V" (widok), "C" (kontroler), ale nie "M" (model).

Przekazywanie danych z kontrolera do widoku

Akcje kontrolera są wywoływane w odpowiedzi na przychodzące żądanie adresu URL. Klasa kontrolera to miejsce, w którym jest napisany kod, który obsługuje przychodzące żądania przeglądarki. Kontroler pobiera dane ze źródła danych i decyduje, jakiego typu odpowiedź ma być wysyłana z powrotem do przeglądarki. Szablony widoków mogą być używane z poziomu kontrolera do generowania i formatowania odpowiedzi HTML dla przeglądarki.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych, aby szablon widoku mógł wyrenderować odpowiedź.

Szablony widoku nie powinny:

  • Wykonaj logikę biznesową
  • Bezpośrednia interakcja z bazą danych.

Szablon widoku powinien działać tylko z danymi dostarczonymi przez kontroler. Utrzymanie tego "rozdzielenia problemów" pomaga zachować kod:

  • Czysty.
  • Testowalny.
  • Łatwy w utrzymaniu.

Obecnie metoda Welcome w klasie HelloWorldController przyjmuje parametr name i parametr ID, a następnie wypisuje wartości bezpośrednio w przeglądarce.

Zamiast renderować tę odpowiedź jako ciąg znaków w kontrolerze, zmień kontroler tak, aby zamiast tego używał szablonu widoku. Szablon widoku generuje dynamiczną odpowiedź, co oznacza, że odpowiednie dane muszą zostać przekazane z kontrolera do widoku w celu wygenerowania odpowiedzi. W tym celu kontroler umieszcza dane dynamiczne (parametry), których potrzebuje szablon widoku w słowniku ViewData . Następnie szablon widoku może uzyskiwać dostęp do danych dynamicznych.

W pliku HelloWorldController.cs zmień metodę Welcome, aby dodać do słownika ViewData wartości Message i NumTimes.

Słownik ViewData jest obiektem dynamicznym, co oznacza, że można użyć dowolnego typu. Obiekt ViewData nie ma zdefiniowanych właściwości, dopóki coś nie zostanie dodane. System powiązania modelu MVC automatycznie mapuje nazwane parametry name i numTimes z ciągu zapytania na parametry w metodzie . Cały HelloWorldController:

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers
{
    public class HelloWorldController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Welcome(string name, int numTimes = 1)
        {
            ViewData["Message"] = "Hello " + name;
            ViewData["NumTimes"] = numTimes;

            return View();
        }
    }
}

Obiekt słownika ViewData zawiera dane, które zostaną przekazane do widoku.

Utwórz szablon widoku powitalnego o nazwie Views/HelloWorld/Welcome.cshtml.

Utworzysz pętlę w szablonie Welcome.cshtml widoku, który wyświetla komunikat "Hello" NumTimes. Zastąp zawartość Views/HelloWorld/Welcome.cshtml pliku następującym kodem:

@{
    ViewData["Title"] = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < (int)ViewData["NumTimes"]; i++)
    {
        <li>@ViewData["Message"]</li>
    }
</ul>

Zapisz zmiany i przejdź do następującego adresu URL:

https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4

Dane są pobierane z adresu URL i przekazywane do kontrolera za pomocą mechanizmu wiązania modelu MVC. Kontroler pakuje dane do słownika ViewData i przekazuje ten obiekt do widoku. Następnie widok renderuje dane jako HTML w przeglądarce.

Privacy widok przedstawiający etykietę powitalną i frazę Hello Rick pokazaną cztery razy

W poprzednim przykładzie użyto słownika ViewData, aby przekazać dane z kontrolera do widoku. W dalszej części samouczka model widoku jest używany do przekazywania danych z kontrolera do widoku. Podejście modelu widoku do przekazywania danych jest preferowane w przypadku podejścia do słownika ViewData .

W następnym samouczku zostanie utworzona baza danych o filmach.