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

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Autor: Rick Anderson

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To czysto hermetyzuje proces generowania odpowiedzi HTML do klienta.

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

  • .cshtml Mieć rozszerzenie pliku.
  • 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 ma następujące działanie:

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

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład Index metoda akcji w poprzednim kodzie.
  • Zazwyczaj zwraca klasę lub pochodzącą IActionResult z ActionResultklasy , a nie typu, takiego 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 — MvcFilm:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybieranie Razor widoku — puste
  • 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 uruchomionej HelloWorldController instrukcji return View();, która określiła, że metoda powinna używać pliku szablonu widoku do renderowania odpowiedzi na przeglądarkę.

  • 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.

@RenderBody() Znajdź wiersz. RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie tworzone strony specyficzne dla widoku, opakowane na stronie układu. Jeśli na przykład wybierzesz Privacy link, Views/Home/Privacy.cshtml widok zostanie renderowany wewnątrz RenderBody metody .

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>

W poprzednim znaczniku wprowadzono następujące zmiany:

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

W poprzednim znaczniku pominięto atrybut pomocnika tagów kotwicy i wartość atrybutu, asp-area=""ponieważ ta aplikacja nie używa obszarów.

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

Zapisz zmiany i wybierz Privacy link. Zwróć uwagę, jak tytuł na karcie przeglądarki wyświetla Privacy zasady — Aplikacja filmowa zamiast Privacy Zasad — MvcFilm

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst zakotwiczenia wyświetlają aplikację movie. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Views/_ViewStart.cshtml Sprawdź plik:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml jest wprowadzany 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 <h2> element, tak jak wyróżniono w następujący sposób:

@{
    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 Title właściwość 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 zmianę i przejdź do https://localhost:{PORT}/HelloWorldadresu .

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 klawisze Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony za pomocą ViewData["Title"] ustawienia w szablonie Index.cshtml widoku i dodatkowego "- Aplikacja filmowa" dodanego w pliku układu.

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 komunikatu "data", "Hello from our View Template!" (Witaj z naszego szablonu widoku) jest jednak zakodowany 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ą służyć z kontrolera do generowania i formatowania odpowiedzi HTML w przeglądarce.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych w celu renderowania odpowiedzi przez szablon widoku.

Nie należy wyświetlać szablonów:

  • Logika biznesowa
  • 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:

  • Czyste.
  • Testować.
  • Utrzymaniu.

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

Zamiast tego kontroler renderuje tę odpowiedź jako ciąg, 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 HelloWorldController.cspliku zmień metodę , Welcome aby dodać Message wartość i NumTimes do słownika ViewData .

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 . Kompletny HelloWorldControllerelement :

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 przy użyciu powią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 ViewData słownik był używany do przekazywania danych 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 filmów.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To czysto hermetyzuje proces generowania odpowiedzi HTML do klienta.

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

  • .cshtml Mieć rozszerzenie pliku.
  • 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 ma następujące działanie:

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

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład Index metoda akcji w poprzednim kodzie.
  • Zazwyczaj zwraca klasę lub pochodzącą IActionResult z ActionResultklasy , a nie typu, takiego 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 — MvcFilm:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybieranie Razor widoku — puste
  • 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 uruchomionej HelloWorldController instrukcji return View();, która określiła, że metoda powinna używać pliku szablonu widoku do renderowania odpowiedzi na przeglądarkę.

  • 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.

@RenderBody() Znajdź wiersz. RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie tworzone strony specyficzne dla widoku, opakowane na stronie układu. Jeśli na przykład wybierzesz Privacy link, Views/Home/Privacy.cshtml widok zostanie renderowany wewnątrz RenderBody metody .

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>

W poprzednim znaczniku wprowadzono następujące zmiany:

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

W poprzednim znaczniku pominięto atrybut pomocnika tagów kotwicy i wartość atrybutu, asp-area=""ponieważ ta aplikacja nie używa obszarów.

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

Zapisz zmiany i wybierz Privacy link. Zwróć uwagę, jak tytuł na karcie przeglądarki wyświetla Privacy zasady — Aplikacja filmowa zamiast Privacy Zasad — MvcFilm

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst zakotwiczenia wyświetlają aplikację movie. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Views/_ViewStart.cshtml Sprawdź plik:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml jest wprowadzany 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 <h2> element, tak jak wyróżniono w następujący sposób:

@{
    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 Title właściwość 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 zmianę i przejdź do https://localhost:{PORT}/HelloWorldadresu .

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 klawisze Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony za pomocą ViewData["Title"] ustawienia w szablonie Index.cshtml widoku i dodatkowego "- Aplikacja filmowa" dodanego w pliku układu.

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 komunikatu "data", "Hello from our View Template!" (Witaj z naszego szablonu widoku) jest jednak zakodowany 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ą służyć z kontrolera do generowania i formatowania odpowiedzi HTML w przeglądarce.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych w celu renderowania odpowiedzi przez szablon widoku.

Nie należy wyświetlać szablonów:

  • Logika biznesowa
  • 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:

  • Czyste.
  • Testować.
  • Utrzymaniu.

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

Zamiast tego kontroler renderuje tę odpowiedź jako ciąg, 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 HelloWorldController.cspliku zmień metodę , Welcome aby dodać Message wartość i NumTimes do słownika ViewData .

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 . Kompletny HelloWorldControllerelement :

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 przy użyciu powią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 ViewData słownik był używany do przekazywania danych 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 filmów.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To czysto hermetyzuje proces generowania odpowiedzi HTML do klienta.

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

  • .cshtml Mieć rozszerzenie pliku.
  • 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 ma następujące działanie:

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

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład Index metoda akcji w poprzednim kodzie.
  • Zazwyczaj zwraca klasę lub pochodzącą IActionResult z ActionResultklasy , a nie typu, takiego 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 — MvcFilm:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybieranie Razor widoku — puste
  • 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 uruchomionej HelloWorldController instrukcji return View();, która określiła, że metoda powinna używać pliku szablonu widoku do renderowania odpowiedzi na przeglądarkę.

  • 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.

@RenderBody() Znajdź wiersz. RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie tworzone strony specyficzne dla widoku, opakowane na stronie układu. Jeśli na przykład wybierzesz Privacy link, Views/Home/Privacy.cshtml widok zostanie renderowany wewnątrz RenderBody metody .

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>

W poprzednim znaczniku wprowadzono następujące zmiany:

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

W poprzednim znaczniku pominięto atrybut pomocnika tagów kotwicy i wartość atrybutu, asp-area=""ponieważ ta aplikacja nie używa obszarów.

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

Zapisz zmiany i wybierz Privacy link. Zwróć uwagę, jak tytuł na karcie przeglądarki wyświetla Privacy zasady — Aplikacja filmowa zamiast Privacy Zasad — MvcFilm

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst zakotwiczenia wyświetlają aplikację movie. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Views/_ViewStart.cshtml Sprawdź plik:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml jest wprowadzany 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 <h2> element, tak jak wyróżniono w następujący sposób:

@{
    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 Title właściwość 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 zmianę i przejdź do https://localhost:{PORT}/HelloWorldadresu .

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 klawisze Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony za pomocą ViewData["Title"] ustawienia w szablonie Index.cshtml widoku i dodatkowego "- Aplikacja filmowa" dodanego w pliku układu.

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 komunikatu "data", "Hello from our View Template!" (Witaj z naszego szablonu widoku) jest jednak zakodowany 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ą służyć z kontrolera do generowania i formatowania odpowiedzi HTML w przeglądarce.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych w celu renderowania odpowiedzi przez szablon widoku.

Nie należy wyświetlać szablonów:

  • Logika biznesowa
  • 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:

  • Czyste.
  • Testować.
  • Utrzymaniu.

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

Zamiast tego kontroler renderuje tę odpowiedź jako ciąg, 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 HelloWorldController.cspliku zmień metodę , Welcome aby dodać Message wartość i NumTimes do słownika ViewData .

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 . Kompletny HelloWorldControllerelement :

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 przy użyciu powią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 ViewData słownik był używany do przekazywania danych 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 filmów.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To czysto hermetyzuje proces generowania odpowiedzi HTML do klienta.

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

  • .cshtml Mieć rozszerzenie pliku.
  • 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 ma następujące działanie:

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

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład Index metoda akcji w poprzednim kodzie.
  • Zazwyczaj zwraca klasę lub pochodzącą IActionResult z ActionResultklasy , a nie typu, takiego 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 — MvcFilm:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybieranie Razor widoku — puste
  • 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 uruchomionej HelloWorldController instrukcji return View();, która określiła, że metoda powinna używać pliku szablonu widoku do renderowania odpowiedzi na przeglądarkę.

  • 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.

@RenderBody() Znajdź wiersz. RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie tworzone strony specyficzne dla widoku, opakowane na stronie układu. Jeśli na przykład wybierzesz Privacy link, Views/Home/Privacy.cshtml widok zostanie renderowany wewnątrz RenderBody metody .

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>

W poprzednim znaczniku wprowadzono następujące zmiany:

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

W poprzednim znaczniku pominięto atrybut pomocnika tagów kotwicy i wartość atrybutu, asp-area=""ponieważ ta aplikacja nie używa obszarów.

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

Zapisz zmiany i wybierz Privacy link. Zwróć uwagę, jak tytuł na karcie przeglądarki wyświetla Privacy zasady — Aplikacja filmowa zamiast Privacy Zasad — MvcFilm

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst zakotwiczenia wyświetlają aplikację movie. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Views/_ViewStart.cshtml Sprawdź plik:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml jest wprowadzany 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 <h2> element, tak jak wyróżniono w następujący sposób:

@{
    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 Title właściwość 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 zmianę i przejdź do https://localhost:{PORT}/HelloWorldadresu .

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 klawisze Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony za pomocą ViewData["Title"] ustawienia w szablonie Index.cshtml widoku i dodatkowego "- Aplikacja filmowa" dodanego w pliku układu.

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 komunikatu "data", "Hello from our View Template!" (Witaj z naszego szablonu widoku) jest jednak zakodowany 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ą służyć z kontrolera do generowania i formatowania odpowiedzi HTML w przeglądarce.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych w celu renderowania odpowiedzi przez szablon widoku.

Nie należy wyświetlać szablonów:

  • Logika biznesowa
  • 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:

  • Czyste.
  • Testować.
  • Utrzymaniu.

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

Zamiast tego kontroler renderuje tę odpowiedź jako ciąg, 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 HelloWorldController.cspliku zmień metodę , Welcome aby dodać Message wartość i NumTimes do słownika ViewData .

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 . Kompletny HelloWorldControllerelement :

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 przy użyciu powią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 ViewData słownik był używany do przekazywania danych 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 filmów.

W tej sekcji zmodyfikujesz klasę HelloWorldController tak, aby korzystała z Razor plików widoku. To czysto hermetyzuje proces generowania odpowiedzi HTML do klienta.

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

  • .cshtml Mieć rozszerzenie pliku.
  • 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 ma następujące działanie:

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

Metody kontrolera:

  • Są nazywane metodami akcji. Na przykład Index metoda akcji w poprzednim kodzie.
  • Zazwyczaj zwraca klasę lub pochodzącą IActionResult z ActionResultklasy , a nie typu, takiego 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 — MvcFilm:

  • W polu wyszukiwania w prawym górnym rogu wprowadź widok
  • Wybieranie Razor widoku — puste
  • 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 uruchomionej HelloWorldController instrukcji return View();, która określiła, że metoda powinna używać pliku szablonu widoku do renderowania odpowiedzi na przeglądarkę.

  • 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.

@RenderBody() Znajdź wiersz. RenderBody jest symbolem zastępczym, w którym są wyświetlane wszystkie tworzone strony specyficzne dla widoku, opakowane na stronie układu. Jeśli na przykład wybierzesz Privacy link, Views/Home/Privacy.cshtml widok zostanie renderowany wewnątrz RenderBody metody .

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>

W poprzednim znaczniku wprowadzono następujące zmiany:

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

W poprzednim znaczniku pominięto atrybut pomocnika tagów kotwicy i wartość atrybutu, asp-area=""ponieważ ta aplikacja nie używa obszarów.

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

Zapisz zmiany i wybierz Privacy link. Zwróć uwagę, jak tytuł na karcie przeglądarki wyświetla Privacy zasady — Aplikacja filmowa zamiast Privacy Zasad — MvcFilm

Privacy tabulator

Wybierz link Home.

Zwróć uwagę, że tytuł i tekst zakotwiczenia wyświetlają aplikację movie. Zmiany zostały wprowadzone raz w szablonie układu, a wszystkie strony w witrynie odzwierciedlają nowy tekst linku i nowy tytuł.

Views/_ViewStart.cshtml Sprawdź plik:

@{
    Layout = "_Layout";
}

Plik Views/_ViewStart.cshtml jest wprowadzany 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 <h2> element, tak jak wyróżniono w następujący sposób:

@{
    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 Title właściwość 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 zmianę i przejdź do https://localhost:{PORT}/HelloWorldadresu .

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 klawisze Ctrl+F5 w przeglądarce, aby wymusić załadowanie odpowiedzi z serwera. Tytuł przeglądarki jest tworzony za pomocą ViewData["Title"] ustawienia w szablonie Index.cshtml widoku i dodatkowego "- Aplikacja filmowa" dodanego w pliku układu.

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 komunikatu "data", "Hello from our View Template!" (Witaj z naszego szablonu widoku) jest jednak zakodowany 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ą służyć z kontrolera do generowania i formatowania odpowiedzi HTML w przeglądarce.

Kontrolery są odpowiedzialne za dostarczanie danych wymaganych w celu renderowania odpowiedzi przez szablon widoku.

Nie należy wyświetlać szablonów:

  • Logika biznesowa
  • 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:

  • Czyste.
  • Testować.
  • Utrzymaniu.

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

Zamiast tego kontroler renderuje tę odpowiedź jako ciąg, 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 HelloWorldController.cspliku zmień metodę , Welcome aby dodać Message wartość i NumTimes do słownika ViewData .

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 . Kompletny HelloWorldControllerelement :

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 przy użyciu powią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 ViewData słownik był używany do przekazywania danych 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 filmów.