Parte 3, adicionar uma exibição a um aplicativo ASP.NET Core MVC

Observação

Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Importante

Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.

Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

De Rick Anderson

Nesta seção, você modificará a classe HelloWorldController para usar arquivos de exibição Razor. Isso resume perfeitamente o processo de geração de respostas HTML a um cliente.

Os modelos de exibição são criados usando Razor. Modelos de exibição baseados em Razor:

  • Tenha uma extensão de arquivo .cshtml.
  • Forneça uma maneira elegante de criar a saída HTML com o C#.

Atualmente, o método Index retorna uma cadeia de caracteres com uma mensagem na classe do controlador. Na classe HelloWorldController, substitua o método Index pelo seguinte código:

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

O código anterior:

  • Chama o método View do controlador.
  • Usa um modelo de exibição para gerar uma resposta HTML.

Métodos do controlador:

  • São chamados demétodos de ação. Por exemplo, o método de ação Index no código anterior.
  • Geralmente, retorna IActionResult ou uma classe ou derivada de ActionResult, não um tipo como string.

Adicionar uma exibição

Clique com o botão direito do mouse na pasta Exibições e, em seguida, Adicionar >Nova Pasta e nomeie a pasta HelloWorld.

Clique com o botão direito do mouse na pasta Views/HelloWorld e, em seguida, clique em Adicionar > Novo Item.

Na caixa de diálogo Adicionar Novo Item, selecione Mostrar Todos os Modelos.

Na caixa de diálogo Adicionar Novo Item – MvcMovie:

  • Na caixa de pesquisa no canto superior direito, insira exibição
  • Selecione Razor Exibição - Vazio
  • Mantenha o valor da caixa Nome, Index.cshtml.
  • Selecione Adicionar

Caixa de diálogo Adicionar Novo Item

Substitua o conteúdo do arquivo de exibição Views/HelloWorld/Index.cshtmlRazor pelo seguinte:

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

<h2>Index</h2>

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

Acesse o diretório https://localhost:{PORT}/HelloWorld:

  • O método Index no HelloWorldController executou a instrução return View();, que especificou que o método deve usar um arquivo de modelo de exibição para renderizar uma resposta para o navegador.

  • Como o nome do arquivo de modo de exibição não foi especificado, o MVC é padronizado para usar o arquivo de exibição padrão. Quando o nome do arquivo de exibição não é especificado, a exibição padrão é retornada. A exibição padrão tem o mesmo nome que o método de ação, Index neste exemplo. O modelo de exibição /Views/HelloWorld/Index.cshtml é usado.

  • A imagem a seguir mostra a cadeia de caracteres "Olá aqui do nosso Modelo de Exibição!" nativa do código do modo de exibição:

    Janela do navegador

Alterar exibições e páginas de layout

Selecione os links de menu MvcMovie, Home e Privacy. Cada página mostra o mesmo layout de menu. O layout do menu é implementado no arquivo Views/Shared/_Layout.cshtml.

Abra o arquivo Views/Shared/_Layout.cshtml .

Os modelos de Layout permitem:

  • Especificar o layout do contêiner HTML de um site em um só lugar.
  • Aplicar o layout do contêiner HTML em várias páginas no site.

Localize a linha @RenderBody(). RenderBody é um espaço reservado em que todas as páginas específicas à exibição criadas são mostradas, encapsuladas na página de layout. Por exemplo, se você selecionar o link Privacy, a exibição Views/Home/Privacy.cshtml será renderizada dentro do método RenderBody.

Substitua o conteúdo do arquivo Views/Shared/_Layout.cshtml pela seguinte marcação. As alterações são realçadas:

<!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>

A marcação anterior fez as seguintes alterações:

  • Três ocorrências de MvcMovie para Movie App.
  • O elemento de âncora <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> para <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>.

Na marcação anterior, o valor do atributo e o asp-area=""atributo do Auxiliar de Marca de Âncora e o valor do atributo foram omitidos porque esse aplicativo não está usando Áreas.

Observação: O controlador Movies não foi implementado. Nesse ponto, o link Movie App não está funcionando.

Salve as alterações e selecione o link Privacy. Observe como o título na guia do navegador agora exibe PrivacyPolítica - Aplicativo de Filme, em vez de PrivacyPolítica - MvcMovie

Privacy guia

Selecione o link Home.

Observe que o título e o texto de âncora mostram Aplicativo de Filme. As alterações foram feitas uma vez no modelo de layout e que todas as páginas do site refletem o novo texto do link e o novo título.

Examine o arquivo Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

O arquivo Views/_ViewStart.cshtml traz o arquivo Views/Shared/_Layout.cshtml para cada exibição. A propriedade Layout pode ser usada para definir outra exibição de layout ou defina-a como null para que nenhum arquivo de layout seja usado.

Abra o arquivo de exibição Views/HelloWorld/Index.cshtml.

Altere o título e o elemento <h2> conforme realçado a seguir:

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

<h2>My Movie List</h2>

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

O título e o elemento <h2> são ligeiramente diferentes para que fique claro qual parte do código altera a exibição.

ViewData["Title"] = "Movie List"; no código acima define a propriedade Title do dicionário ViewData como “Lista de Filmes”. A propriedade Title é usada no elemento HTML <title> na página de layout:

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

Salve as alterações e navegue para https://localhost:{PORT}/HelloWorld.

Observe que as seguintes alterações foram feitas:

  • Título do navegador.
  • Título primário.
  • Títulos secundários.

Se não houver alterações no navegador, pode ser que o conteúdo que está sendo exibido esteja armazenado em cache. Pressione Ctrl+F5 no navegador para forçar a resposta do servidor a ser carregada. O título do navegador é criado com ViewData["Title"] que definimos no modelo de exibição Index.cshtml e o “- Aplicativo de Filme” adicionado no arquivo de layout.

O conteúdo do modelo de exibição Index.cshtml é mesclado com o modelo de exibição Views/Shared/_Layout.cshtml . Uma única resposta HTML é enviada ao navegador. Os modelos de layout facilitam a realização de alterações que se aplicam a todas as páginas de um aplicativo. Para saber mais, consulte Layout.

Exibição de Lista de Filmes

No entanto, a pequena quantidade de "dados", a mensagem "Olá aqui do nosso Modelo de Exibição!", é nativa do código. O aplicativo MVC tem um “V” (exibição), um “C” (controlador), mas ainda nenhum “M” (modelo).

Passando dados do controlador para a exibição

As ações do controlador são invocadas em resposta a uma solicitação de URL de entrada. Uma classe de controlador é o local em que o código é escrito e que manipula as solicitações recebidas do navegador. O controlador recupera dados de uma fonte de dados e decide qual tipo de resposta será enviada novamente para o navegador. Modelos de exibição podem ser usados em um controlador para gerar e formatar uma resposta HTML para o navegador.

Os controladores são responsáveis por fornecer os dados necessários para que um modelo de exibição renderize uma resposta.

Os modelos de exibição não devem:

  • Processar lógicas de negócios
  • Interagir diretamente com algum banco de dados.

O modelo de exibição deve funcionar somente com os dados fornecidos pelo controlador. Manter essa “separação de preocupações” ajuda a manter o código:

  • Limpo.
  • Testável.
  • Descomplicado em relação à manutenção.

Atualmente, o método Welcome na classe HelloWorldController usa um name e um parâmetro IDe, em seguida, gera os valores de saída diretamente no navegador.

Em vez de fazer com que o controlador renderize a resposta como uma cadeia de caracteres, altere o controlador para que ele use um modelo de exibição. O modelo de exibição gera uma resposta dinâmica, o que significa que é necessário passar os dados apropriados do controlador para a exibição para gerar a resposta. Faça isso fazendo com que o controlador coloque os dados dinâmicos (parâmetros) que o modelo de exibição precisa em um dicionário ViewData. O modelo de exibição pode então acessar os dados dinâmicos.

Em HelloWorldController.cs, altere o método Welcome para adicionar um valor Message e NumTimes ao dicionário ViewData.

O dicionário ViewData é um objeto dinâmico, o que significa que qualquer tipo pode ser usado. O objeto ViewData não tem propriedades definidas até que algo seja adicionado. O sistema de model binding do MVC mapeia automaticamente os parâmetros nomeados name e numTimes da cadeia de caracteres de consulta para os parâmetros do método. O HelloWorldController completo:

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();
    }
}

O objeto de dicionário ViewData contém dados que serão passados para a exibição.

Criar um modelo de exibição de boas-vindas chamado Views/HelloWorld/Welcome.cshtml.

Você criará um loop no modelo de exibição Welcome.cshtml que exibe “Olá” NumTimes. Substitua o conteúdo de Views/HelloWorld/Welcome.cshtml pelo fornecido a seguir:

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

<h2>Welcome</h2>

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

Salve as alterações e navegue para a seguinte URL:

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

Os dados são obtidos da URL e passados para o controlador usando o associador de modelo MVC. O controlador empacota os dados em um dicionário ViewData e passa esse objeto para a exibição. Em seguida, a exibição renderiza os dados como HTML para o navegador.

Privacy exibição que mostra um rótulo de boas-vindas e a frase

No exemplo acima, o dicionário ViewData foi usado para passar dados do controlador para uma exibição. Mais adiante no tutorial, um modelo de exibição será usado para passar dados de um controlador para uma exibição. A abordagem do modelo de exibição para passar dados é geralmente a preferida em relação à abordagem do dicionário ViewData.

No próximo tutorial, será criado um banco de dados de filmes.

Nesta seção, você modificará a classe HelloWorldController para usar arquivos de exibição Razor. Isso resume perfeitamente o processo de geração de respostas HTML a um cliente.

Os modelos de exibição são criados usando Razor. Modelos de exibição baseados em Razor:

  • Tenha uma extensão de arquivo .cshtml.
  • Forneça uma maneira elegante de criar a saída HTML com o C#.

Atualmente, o método Index retorna uma cadeia de caracteres com uma mensagem na classe do controlador. Na classe HelloWorldController, substitua o método Index pelo seguinte código:

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

O código anterior:

  • Chama o método View do controlador.
  • Usa um modelo de exibição para gerar uma resposta HTML.

Métodos do controlador:

  • São chamados demétodos de ação. Por exemplo, o método de ação Index no código anterior.
  • Geralmente, retorna IActionResult ou uma classe ou derivada de ActionResult, não um tipo como string.

Adicionar uma exibição

Clique com o botão direito do mouse na pasta Exibições e, em seguida, Adicionar >Nova Pasta e nomeie a pasta HelloWorld.

Clique com o botão direito do mouse na pasta Views/HelloWorld e, em seguida, clique em Adicionar > Novo Item.

Na caixa de diálogo Adicionar Novo Item – MvcMovie:

  • Na caixa de pesquisa no canto superior direito, insira exibição
  • Selecione Razor Exibição - Vazio
  • Mantenha o valor da caixa Nome, Index.cshtml.
  • Selecione Adicionar

Caixa de diálogo Adicionar Novo Item

Substitua o conteúdo do arquivo de exibição Views/HelloWorld/Index.cshtmlRazor pelo seguinte:

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

<h2>Index</h2>

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

Acesse o diretório https://localhost:{PORT}/HelloWorld:

  • O método Index no HelloWorldController executou a instrução return View();, que especificou que o método deve usar um arquivo de modelo de exibição para renderizar uma resposta para o navegador.

  • Como o nome do arquivo de modo de exibição não foi especificado, o MVC é padronizado para usar o arquivo de exibição padrão. Quando o nome do arquivo de exibição não é especificado, a exibição padrão é retornada. A exibição padrão tem o mesmo nome que o método de ação, Index neste exemplo. O modelo de exibição /Views/HelloWorld/Index.cshtml é usado.

  • A imagem a seguir mostra a cadeia de caracteres "Olá aqui do nosso Modelo de Exibição!" nativa do código do modo de exibição:

    Janela do navegador

Alterar exibições e páginas de layout

Selecione os links de menu MvcMovie, Home e Privacy. Cada página mostra o mesmo layout de menu. O layout do menu é implementado no arquivo Views/Shared/_Layout.cshtml.

Abra o arquivo Views/Shared/_Layout.cshtml .

Os modelos de Layout permitem:

  • Especificar o layout do contêiner HTML de um site em um só lugar.
  • Aplicar o layout do contêiner HTML em várias páginas no site.

Localize a linha @RenderBody(). RenderBody é um espaço reservado em que todas as páginas específicas à exibição criadas são mostradas, encapsuladas na página de layout. Por exemplo, se você selecionar o link Privacy, a exibição Views/Home/Privacy.cshtml será renderizada dentro do método RenderBody.

Substitua o conteúdo do arquivo Views/Shared/_Layout.cshtml pela seguinte marcação. As alterações são realçadas:

<!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>

A marcação anterior fez as seguintes alterações:

  • Três ocorrências de MvcMovie para Movie App.
  • O elemento de âncora <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> para <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>.

Na marcação anterior, o valor do atributo e o asp-area=""atributo do Auxiliar de Marca de Âncora e o valor do atributo foram omitidos porque esse aplicativo não está usando Áreas.

Observação: O controlador Movies não foi implementado. Nesse ponto, o link Movie App não está funcionando.

Salve as alterações e selecione o link Privacy. Observe como o título na guia do navegador agora exibe PrivacyPolítica - Aplicativo de Filme, em vez de PrivacyPolítica - MvcMovie

Privacy guia

Selecione o link Home.

Observe que o título e o texto de âncora mostram Aplicativo de Filme. As alterações foram feitas uma vez no modelo de layout e que todas as páginas do site refletem o novo texto do link e o novo título.

Examine o arquivo Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

O arquivo Views/_ViewStart.cshtml traz o arquivo Views/Shared/_Layout.cshtml para cada exibição. A propriedade Layout pode ser usada para definir outra exibição de layout ou defina-a como null para que nenhum arquivo de layout seja usado.

Abra o arquivo de exibição Views/HelloWorld/Index.cshtml.

Altere o título e o elemento <h2> conforme realçado a seguir:

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

<h2>My Movie List</h2>

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

O título e o elemento <h2> são ligeiramente diferentes para que fique claro qual parte do código altera a exibição.

ViewData["Title"] = "Movie List"; no código acima define a propriedade Title do dicionário ViewData como “Lista de Filmes”. A propriedade Title é usada no elemento HTML <title> na página de layout:

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

Salve as alterações e navegue para https://localhost:{PORT}/HelloWorld.

Observe que as seguintes alterações foram feitas:

  • Título do navegador.
  • Título primário.
  • Títulos secundários.

Se não houver alterações no navegador, pode ser que o conteúdo que está sendo exibido esteja armazenado em cache. Pressione Ctrl+F5 no navegador para forçar a resposta do servidor a ser carregada. O título do navegador é criado com ViewData["Title"] que definimos no modelo de exibição Index.cshtml e o “- Aplicativo de Filme” adicionado no arquivo de layout.

O conteúdo do modelo de exibição Index.cshtml é mesclado com o modelo de exibição Views/Shared/_Layout.cshtml . Uma única resposta HTML é enviada ao navegador. Os modelos de layout facilitam a realização de alterações que se aplicam a todas as páginas de um aplicativo. Para saber mais, consulte Layout.

Exibição de Lista de Filmes

No entanto, a pequena quantidade de "dados", a mensagem "Olá aqui do nosso Modelo de Exibição!", é nativa do código. O aplicativo MVC tem um “V” (exibição), um “C” (controlador), mas ainda nenhum “M” (modelo).

Passando dados do controlador para a exibição

As ações do controlador são invocadas em resposta a uma solicitação de URL de entrada. Uma classe de controlador é o local em que o código é escrito e que manipula as solicitações recebidas do navegador. O controlador recupera dados de uma fonte de dados e decide qual tipo de resposta será enviada novamente para o navegador. Modelos de exibição podem ser usados em um controlador para gerar e formatar uma resposta HTML para o navegador.

Os controladores são responsáveis por fornecer os dados necessários para que um modelo de exibição renderize uma resposta.

Os modelos de exibição não devem:

  • Processar lógicas de negócios
  • Interagir diretamente com algum banco de dados.

O modelo de exibição deve funcionar somente com os dados fornecidos pelo controlador. Manter essa “separação de preocupações” ajuda a manter o código:

  • Limpo.
  • Testável.
  • Descomplicado em relação à manutenção.

Atualmente, o método Welcome na classe HelloWorldController usa um name e um parâmetro IDe, em seguida, gera os valores de saída diretamente no navegador.

Em vez de fazer com que o controlador renderize a resposta como uma cadeia de caracteres, altere o controlador para que ele use um modelo de exibição. O modelo de exibição gera uma resposta dinâmica, o que significa que é necessário passar os dados apropriados do controlador para a exibição para gerar a resposta. Faça isso fazendo com que o controlador coloque os dados dinâmicos (parâmetros) que o modelo de exibição precisa em um dicionário ViewData. O modelo de exibição pode então acessar os dados dinâmicos.

Em HelloWorldController.cs, altere o método Welcome para adicionar um valor Message e NumTimes ao dicionário ViewData.

O dicionário ViewData é um objeto dinâmico, o que significa que qualquer tipo pode ser usado. O objeto ViewData não tem propriedades definidas até que algo seja adicionado. O sistema de model binding do MVC mapeia automaticamente os parâmetros nomeados name e numTimes da cadeia de caracteres de consulta para os parâmetros do método. O HelloWorldController completo:

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();
    }
}

O objeto de dicionário ViewData contém dados que serão passados para a exibição.

Criar um modelo de exibição de boas-vindas chamado Views/HelloWorld/Welcome.cshtml.

Você criará um loop no modelo de exibição Welcome.cshtml que exibe “Olá” NumTimes. Substitua o conteúdo de Views/HelloWorld/Welcome.cshtml pelo fornecido a seguir:

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

<h2>Welcome</h2>

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

Salve as alterações e navegue para a seguinte URL:

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

Os dados são obtidos da URL e passados para o controlador usando o associador de modelo MVC. O controlador empacota os dados em um dicionário ViewData e passa esse objeto para a exibição. Em seguida, a exibição renderiza os dados como HTML para o navegador.

Privacy exibição que mostra um rótulo de boas-vindas e a frase

No exemplo acima, o dicionário ViewData foi usado para passar dados do controlador para uma exibição. Mais adiante no tutorial, um modelo de exibição será usado para passar dados de um controlador para uma exibição. A abordagem do modelo de exibição para passar dados é geralmente a preferida em relação à abordagem do dicionário ViewData.

No próximo tutorial, será criado um banco de dados de filmes.

Nesta seção, você modificará a classe HelloWorldController para usar arquivos de exibição Razor. Isso resume perfeitamente o processo de geração de respostas HTML a um cliente.

Os modelos de exibição são criados usando Razor. Modelos de exibição baseados em Razor:

  • Tenha uma extensão de arquivo .cshtml.
  • Forneça uma maneira elegante de criar a saída HTML com o C#.

Atualmente, o método Index retorna uma cadeia de caracteres com uma mensagem na classe do controlador. Na classe HelloWorldController, substitua o método Index pelo seguinte código:

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

O código anterior:

  • Chama o método View do controlador.
  • Usa um modelo de exibição para gerar uma resposta HTML.

Métodos do controlador:

  • São chamados demétodos de ação. Por exemplo, o método de ação Index no código anterior.
  • Geralmente, retorna IActionResult ou uma classe ou derivada de ActionResult, não um tipo como string.

Adicionar uma exibição

Clique com o botão direito do mouse na pasta Exibições e, em seguida, Adicionar >Nova Pasta e nomeie a pasta HelloWorld.

Clique com o botão direito do mouse na pasta Views/HelloWorld e, em seguida, clique em Adicionar > Novo Item.

Na caixa de diálogo Adicionar Novo Item – MvcMovie:

  • Na caixa de pesquisa no canto superior direito, insira exibição
  • Selecione Razor Exibição - Vazio
  • Mantenha o valor da caixa Nome, Index.cshtml.
  • Selecione Adicionar

Caixa de diálogo Adicionar Novo Item

Substitua o conteúdo do arquivo de exibição Views/HelloWorld/Index.cshtmlRazor pelo seguinte:

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

<h2>Index</h2>

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

Acesse o diretório https://localhost:{PORT}/HelloWorld:

  • O método Index no HelloWorldController executou a instrução return View();, que especificou que o método deve usar um arquivo de modelo de exibição para renderizar uma resposta para o navegador.

  • Como o nome do arquivo de modo de exibição não foi especificado, o MVC é padronizado para usar o arquivo de exibição padrão. Quando o nome do arquivo de exibição não é especificado, a exibição padrão é retornada. A exibição padrão tem o mesmo nome que o método de ação, Index neste exemplo. O modelo de exibição /Views/HelloWorld/Index.cshtml é usado.

  • A imagem a seguir mostra a cadeia de caracteres "Olá aqui do nosso Modelo de Exibição!" nativa do código do modo de exibição:

    Janela do navegador

Alterar exibições e páginas de layout

Selecione os links de menu MvcMovie, Home e Privacy. Cada página mostra o mesmo layout de menu. O layout do menu é implementado no arquivo Views/Shared/_Layout.cshtml.

Abra o arquivo Views/Shared/_Layout.cshtml .

Os modelos de Layout permitem:

  • Especificar o layout do contêiner HTML de um site em um só lugar.
  • Aplicar o layout do contêiner HTML em várias páginas no site.

Localize a linha @RenderBody(). RenderBody é um espaço reservado em que todas as páginas específicas à exibição criadas são mostradas, encapsuladas na página de layout. Por exemplo, se você selecionar o link Privacy, a exibição Views/Home/Privacy.cshtml será renderizada dentro do método RenderBody.

Substitua o conteúdo do arquivo Views/Shared/_Layout.cshtml pela seguinte marcação. As alterações são realçadas:

<!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>

A marcação anterior fez as seguintes alterações:

  • Três ocorrências de MvcMovie para Movie App.
  • O elemento de âncora <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> para <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>.

Na marcação anterior, o valor do atributo e o asp-area=""atributo do Auxiliar de Marca de Âncora e o valor do atributo foram omitidos porque esse aplicativo não está usando Áreas.

Observação: O controlador Movies não foi implementado. Nesse ponto, o link Movie App não está funcionando.

Salve as alterações e selecione o link Privacy. Observe como o título na guia do navegador agora exibe PrivacyPolítica - Aplicativo de Filme, em vez de PrivacyPolítica - MvcMovie

Privacy guia

Selecione o link Home.

Observe que o título e o texto de âncora mostram Aplicativo de Filme. As alterações foram feitas uma vez no modelo de layout e que todas as páginas do site refletem o novo texto do link e o novo título.

Examine o arquivo Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

O arquivo Views/_ViewStart.cshtml traz o arquivo Views/Shared/_Layout.cshtml para cada exibição. A propriedade Layout pode ser usada para definir outra exibição de layout ou defina-a como null para que nenhum arquivo de layout seja usado.

Abra o arquivo de exibição Views/HelloWorld/Index.cshtml.

Altere o título e o elemento <h2> conforme realçado a seguir:

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

<h2>My Movie List</h2>

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

O título e o elemento <h2> são ligeiramente diferentes para que fique claro qual parte do código altera a exibição.

ViewData["Title"] = "Movie List"; no código acima define a propriedade Title do dicionário ViewData como “Lista de Filmes”. A propriedade Title é usada no elemento HTML <title> na página de layout:

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

Salve as alterações e navegue para https://localhost:{PORT}/HelloWorld.

Observe que as seguintes alterações foram feitas:

  • Título do navegador.
  • Título primário.
  • Títulos secundários.

Se não houver alterações no navegador, pode ser que o conteúdo que está sendo exibido esteja armazenado em cache. Pressione Ctrl+F5 no navegador para forçar a resposta do servidor a ser carregada. O título do navegador é criado com ViewData["Title"] que definimos no modelo de exibição Index.cshtml e o “- Aplicativo de Filme” adicionado no arquivo de layout.

O conteúdo do modelo de exibição Index.cshtml é mesclado com o modelo de exibição Views/Shared/_Layout.cshtml . Uma única resposta HTML é enviada ao navegador. Os modelos de layout facilitam a realização de alterações que se aplicam a todas as páginas de um aplicativo. Para saber mais, consulte Layout.

Exibição de Lista de Filmes

No entanto, a pequena quantidade de "dados", a mensagem "Olá aqui do nosso Modelo de Exibição!", é nativa do código. O aplicativo MVC tem um “V” (exibição), um “C” (controlador), mas ainda nenhum “M” (modelo).

Passando dados do controlador para a exibição

As ações do controlador são invocadas em resposta a uma solicitação de URL de entrada. Uma classe de controlador é o local em que o código é escrito e que manipula as solicitações recebidas do navegador. O controlador recupera dados de uma fonte de dados e decide qual tipo de resposta será enviada novamente para o navegador. Modelos de exibição podem ser usados em um controlador para gerar e formatar uma resposta HTML para o navegador.

Os controladores são responsáveis por fornecer os dados necessários para que um modelo de exibição renderize uma resposta.

Os modelos de exibição não devem:

  • Processar lógicas de negócios
  • Interagir diretamente com algum banco de dados.

O modelo de exibição deve funcionar somente com os dados fornecidos pelo controlador. Manter essa “separação de preocupações” ajuda a manter o código:

  • Limpo.
  • Testável.
  • Descomplicado em relação à manutenção.

Atualmente, o método Welcome na classe HelloWorldController usa um name e um parâmetro IDe, em seguida, gera os valores de saída diretamente no navegador.

Em vez de fazer com que o controlador renderize a resposta como uma cadeia de caracteres, altere o controlador para que ele use um modelo de exibição. O modelo de exibição gera uma resposta dinâmica, o que significa que é necessário passar os dados apropriados do controlador para a exibição para gerar a resposta. Faça isso fazendo com que o controlador coloque os dados dinâmicos (parâmetros) que o modelo de exibição precisa em um dicionário ViewData. O modelo de exibição pode então acessar os dados dinâmicos.

Em HelloWorldController.cs, altere o método Welcome para adicionar um valor Message e NumTimes ao dicionário ViewData.

O dicionário ViewData é um objeto dinâmico, o que significa que qualquer tipo pode ser usado. O objeto ViewData não tem propriedades definidas até que algo seja adicionado. O sistema de model binding do MVC mapeia automaticamente os parâmetros nomeados name e numTimes da cadeia de caracteres de consulta para os parâmetros do método. O HelloWorldController completo:

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();
        }
    }
}

O objeto de dicionário ViewData contém dados que serão passados para a exibição.

Criar um modelo de exibição de boas-vindas chamado Views/HelloWorld/Welcome.cshtml.

Você criará um loop no modelo de exibição Welcome.cshtml que exibe “Olá” NumTimes. Substitua o conteúdo de Views/HelloWorld/Welcome.cshtml pelo fornecido a seguir:

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

<h2>Welcome</h2>

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

Salve as alterações e navegue para a seguinte URL:

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

Os dados são obtidos da URL e passados para o controlador usando o associador de modelo MVC. O controlador empacota os dados em um dicionário ViewData e passa esse objeto para a exibição. Em seguida, a exibição renderiza os dados como HTML para o navegador.

Privacy exibição que mostra um rótulo de boas-vindas e a frase

No exemplo acima, o dicionário ViewData foi usado para passar dados do controlador para uma exibição. Mais adiante no tutorial, um modelo de exibição será usado para passar dados de um controlador para uma exibição. A abordagem do modelo de exibição para passar dados é geralmente a preferida em relação à abordagem do dicionário ViewData.

No próximo tutorial, será criado um banco de dados de filmes.

Nesta seção, você modificará a classe HelloWorldController para usar arquivos de exibição Razor. Isso resume perfeitamente o processo de geração de respostas HTML a um cliente.

Os modelos de exibição são criados usando Razor. Modelos de exibição baseados em Razor:

  • Tenha uma extensão de arquivo .cshtml.
  • Forneça uma maneira elegante de criar a saída HTML com o C#.

Atualmente, o método Index retorna uma cadeia de caracteres com uma mensagem na classe do controlador. Na classe HelloWorldController, substitua o método Index pelo seguinte código:

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

O código anterior:

  • Chama o método View do controlador.
  • Usa um modelo de exibição para gerar uma resposta HTML.

Métodos do controlador:

  • São chamados demétodos de ação. Por exemplo, o método de ação Index no código anterior.
  • Geralmente, retorna IActionResult ou uma classe ou derivada de ActionResult, não um tipo como string.

Adicionar uma exibição

Clique com o botão direito do mouse na pasta Exibições e, em seguida, Adicionar >Nova Pasta e nomeie a pasta HelloWorld.

Clique com o botão direito do mouse na pasta Views/HelloWorld e, em seguida, clique em Adicionar > Novo Item.

Na caixa de diálogo Adicionar Novo Item – MvcMovie:

  • Na caixa de pesquisa no canto superior direito, insira exibição
  • Selecione Razor Exibição - Vazio
  • Mantenha o valor da caixa Nome, Index.cshtml.
  • Selecione Adicionar

Caixa de diálogo Adicionar Novo Item

Substitua o conteúdo do arquivo de exibição Views/HelloWorld/Index.cshtmlRazor pelo seguinte:

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

<h2>Index</h2>

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

Acesse o diretório https://localhost:{PORT}/HelloWorld:

  • O método Index no HelloWorldController executou a instrução return View();, que especificou que o método deve usar um arquivo de modelo de exibição para renderizar uma resposta para o navegador.

  • Como o nome do arquivo de modo de exibição não foi especificado, o MVC é padronizado para usar o arquivo de exibição padrão. Quando o nome do arquivo de exibição não é especificado, a exibição padrão é retornada. A exibição padrão tem o mesmo nome que o método de ação, Index neste exemplo. O modelo de exibição /Views/HelloWorld/Index.cshtml é usado.

  • A imagem a seguir mostra a cadeia de caracteres "Olá aqui do nosso Modelo de Exibição!" nativa do código do modo de exibição:

    Janela do navegador

Alterar exibições e páginas de layout

Selecione os links de menu MvcMovie, Home e Privacy. Cada página mostra o mesmo layout de menu. O layout do menu é implementado no arquivo Views/Shared/_Layout.cshtml.

Abra o arquivo Views/Shared/_Layout.cshtml .

Os modelos de Layout permitem:

  • Especificar o layout do contêiner HTML de um site em um só lugar.
  • Aplicar o layout do contêiner HTML em várias páginas no site.

Localize a linha @RenderBody(). RenderBody é um espaço reservado em que todas as páginas específicas à exibição criadas são mostradas, encapsuladas na página de layout. Por exemplo, se você selecionar o link Privacy, a exibição Views/Home/Privacy.cshtml será renderizada dentro do método RenderBody.

Substitua o conteúdo do arquivo Views/Shared/_Layout.cshtml pela seguinte marcação. As alterações são realçadas:

<!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>

A marcação anterior fez as seguintes alterações:

  • Três ocorrências de MvcMovie para Movie App.
  • O elemento de âncora <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> para <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>.

Na marcação anterior, o valor do atributo e o asp-area=""atributo do Auxiliar de Marca de Âncora e o valor do atributo foram omitidos porque esse aplicativo não está usando Áreas.

Observação: O controlador Movies não foi implementado. Nesse ponto, o link Movie App não está funcionando.

Salve as alterações e selecione o link Privacy. Observe como o título na guia do navegador agora exibe PrivacyPolítica - Aplicativo de Filme, em vez de PrivacyPolítica - MvcMovie

Privacy guia

Selecione o link Home.

Observe que o título e o texto de âncora mostram Aplicativo de Filme. As alterações foram feitas uma vez no modelo de layout e que todas as páginas do site refletem o novo texto do link e o novo título.

Examine o arquivo Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

O arquivo Views/_ViewStart.cshtml traz o arquivo Views/Shared/_Layout.cshtml para cada exibição. A propriedade Layout pode ser usada para definir outra exibição de layout ou defina-a como null para que nenhum arquivo de layout seja usado.

Abra o arquivo de exibição Views/HelloWorld/Index.cshtml.

Altere o título e o elemento <h2> conforme realçado a seguir:

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

<h2>My Movie List</h2>

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

O título e o elemento <h2> são ligeiramente diferentes para que fique claro qual parte do código altera a exibição.

ViewData["Title"] = "Movie List"; no código acima define a propriedade Title do dicionário ViewData como “Lista de Filmes”. A propriedade Title é usada no elemento HTML <title> na página de layout:

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

Salve as alterações e navegue para https://localhost:{PORT}/HelloWorld.

Observe que as seguintes alterações foram feitas:

  • Título do navegador.
  • Título primário.
  • Títulos secundários.

Se não houver alterações no navegador, pode ser que o conteúdo que está sendo exibido esteja armazenado em cache. Pressione Ctrl+F5 no navegador para forçar a resposta do servidor a ser carregada. O título do navegador é criado com ViewData["Title"] que definimos no modelo de exibição Index.cshtml e o “- Aplicativo de Filme” adicionado no arquivo de layout.

O conteúdo do modelo de exibição Index.cshtml é mesclado com o modelo de exibição Views/Shared/_Layout.cshtml . Uma única resposta HTML é enviada ao navegador. Os modelos de layout facilitam a realização de alterações que se aplicam a todas as páginas de um aplicativo. Para saber mais, consulte Layout.

Exibição de Lista de Filmes

No entanto, a pequena quantidade de "dados", a mensagem "Olá aqui do nosso Modelo de Exibição!", é nativa do código. O aplicativo MVC tem um “V” (exibição), um “C” (controlador), mas ainda nenhum “M” (modelo).

Passando dados do controlador para a exibição

As ações do controlador são invocadas em resposta a uma solicitação de URL de entrada. Uma classe de controlador é o local em que o código é escrito e que manipula as solicitações recebidas do navegador. O controlador recupera dados de uma fonte de dados e decide qual tipo de resposta será enviada novamente para o navegador. Modelos de exibição podem ser usados em um controlador para gerar e formatar uma resposta HTML para o navegador.

Os controladores são responsáveis por fornecer os dados necessários para que um modelo de exibição renderize uma resposta.

Os modelos de exibição não devem:

  • Processar lógicas de negócios
  • Interagir diretamente com algum banco de dados.

O modelo de exibição deve funcionar somente com os dados fornecidos pelo controlador. Manter essa “separação de preocupações” ajuda a manter o código:

  • Limpo.
  • Testável.
  • Descomplicado em relação à manutenção.

Atualmente, o método Welcome na classe HelloWorldController usa um name e um parâmetro IDe, em seguida, gera os valores de saída diretamente no navegador.

Em vez de fazer com que o controlador renderize a resposta como uma cadeia de caracteres, altere o controlador para que ele use um modelo de exibição. O modelo de exibição gera uma resposta dinâmica, o que significa que é necessário passar os dados apropriados do controlador para a exibição para gerar a resposta. Faça isso fazendo com que o controlador coloque os dados dinâmicos (parâmetros) que o modelo de exibição precisa em um dicionário ViewData. O modelo de exibição pode então acessar os dados dinâmicos.

Em HelloWorldController.cs, altere o método Welcome para adicionar um valor Message e NumTimes ao dicionário ViewData.

O dicionário ViewData é um objeto dinâmico, o que significa que qualquer tipo pode ser usado. O objeto ViewData não tem propriedades definidas até que algo seja adicionado. O sistema de model binding do MVC mapeia automaticamente os parâmetros nomeados name e numTimes da cadeia de caracteres de consulta para os parâmetros do método. O HelloWorldController completo:

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();
        }
    }
}

O objeto de dicionário ViewData contém dados que serão passados para a exibição.

Criar um modelo de exibição de boas-vindas chamado Views/HelloWorld/Welcome.cshtml.

Você criará um loop no modelo de exibição Welcome.cshtml que exibe “Olá” NumTimes. Substitua o conteúdo de Views/HelloWorld/Welcome.cshtml pelo fornecido a seguir:

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

<h2>Welcome</h2>

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

Salve as alterações e navegue para a seguinte URL:

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

Os dados são obtidos da URL e passados para o controlador usando o associador de modelo MVC. O controlador empacota os dados em um dicionário ViewData e passa esse objeto para a exibição. Em seguida, a exibição renderiza os dados como HTML para o navegador.

Privacy exibição que mostra um rótulo de boas-vindas e a frase

No exemplo acima, o dicionário ViewData foi usado para passar dados do controlador para uma exibição. Mais adiante no tutorial, um modelo de exibição será usado para passar dados de um controlador para uma exibição. A abordagem do modelo de exibição para passar dados é geralmente a preferida em relação à abordagem do dicionário ViewData.

No próximo tutorial, será criado um banco de dados de filmes.

Nesta seção, você modificará a classe HelloWorldController para usar arquivos de exibição Razor. Isso resume perfeitamente o processo de geração de respostas HTML a um cliente.

Os modelos de exibição são criados usando Razor. Modelos de exibição baseados em Razor:

  • Tenha uma extensão de arquivo .cshtml.
  • Forneça uma maneira elegante de criar a saída HTML com o C#.

Atualmente, o método Index retorna uma cadeia de caracteres com uma mensagem na classe do controlador. Na classe HelloWorldController, substitua o método Index pelo seguinte código:

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

O código anterior:

  • Chama o método View do controlador.
  • Usa um modelo de exibição para gerar uma resposta HTML.

Métodos do controlador:

  • São chamados demétodos de ação. Por exemplo, o método de ação Index no código anterior.
  • Geralmente, retorna IActionResult ou uma classe ou derivada de ActionResult, não um tipo como string.

Adicionar uma exibição

Clique com o botão direito do mouse na pasta Exibições e, em seguida, Adicionar >Nova Pasta e nomeie a pasta HelloWorld.

Clique com o botão direito do mouse na pasta Views/HelloWorld e, em seguida, clique em Adicionar > Novo Item.

Na caixa de diálogo Adicionar Novo Item – MvcMovie:

  • Na caixa de pesquisa no canto superior direito, insira exibição
  • Selecione Razor Exibição - Vazio
  • Mantenha o valor da caixa Nome, Index.cshtml.
  • Selecione Adicionar

Caixa de diálogo Adicionar Novo Item

Substitua o conteúdo do arquivo de exibição Views/HelloWorld/Index.cshtmlRazor pelo seguinte:

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

<h2>Index</h2>

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

Acesse o diretório https://localhost:{PORT}/HelloWorld:

  • O método Index no HelloWorldController executou a instrução return View();, que especificou que o método deve usar um arquivo de modelo de exibição para renderizar uma resposta para o navegador.

  • Como o nome do arquivo de modo de exibição não foi especificado, o MVC é padronizado para usar o arquivo de exibição padrão. Quando o nome do arquivo de exibição não é especificado, a exibição padrão é retornada. A exibição padrão tem o mesmo nome que o método de ação, Index neste exemplo. O modelo de exibição /Views/HelloWorld/Index.cshtml é usado.

  • A imagem a seguir mostra a cadeia de caracteres "Olá aqui do nosso Modelo de Exibição!" nativa do código do modo de exibição:

    Janela do navegador

Alterar exibições e páginas de layout

Selecione os links de menu MvcMovie, Home e Privacy. Cada página mostra o mesmo layout de menu. O layout do menu é implementado no arquivo Views/Shared/_Layout.cshtml.

Abra o arquivo Views/Shared/_Layout.cshtml .

Os modelos de Layout permitem:

  • Especificar o layout do contêiner HTML de um site em um só lugar.
  • Aplicar o layout do contêiner HTML em várias páginas no site.

Localize a linha @RenderBody(). RenderBody é um espaço reservado em que todas as páginas específicas à exibição criadas são mostradas, encapsuladas na página de layout. Por exemplo, se você selecionar o link Privacy, a exibição Views/Home/Privacy.cshtml será renderizada dentro do método RenderBody.

Substitua o conteúdo do arquivo Views/Shared/_Layout.cshtml pela seguinte marcação. As alterações são realçadas:

<!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>

A marcação anterior fez as seguintes alterações:

  • Três ocorrências de MvcMovie para Movie App.
  • O elemento de âncora <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a> para <a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>.

Na marcação anterior, o valor do atributo e o asp-area=""atributo do Auxiliar de Marca de Âncora e o valor do atributo foram omitidos porque esse aplicativo não está usando Áreas.

Observação: O controlador Movies não foi implementado. Nesse ponto, o link Movie App não está funcionando.

Salve as alterações e selecione o link Privacy. Observe como o título na guia do navegador agora exibe PrivacyPolítica - Aplicativo de Filme, em vez de PrivacyPolítica - MvcMovie

Privacy guia

Selecione o link Home.

Observe que o título e o texto de âncora mostram Aplicativo de Filme. As alterações foram feitas uma vez no modelo de layout e que todas as páginas do site refletem o novo texto do link e o novo título.

Examine o arquivo Views/_ViewStart.cshtml:

@{
    Layout = "_Layout";
}

O arquivo Views/_ViewStart.cshtml traz o arquivo Views/Shared/_Layout.cshtml para cada exibição. A propriedade Layout pode ser usada para definir outra exibição de layout ou defina-a como null para que nenhum arquivo de layout seja usado.

Abra o arquivo de exibição Views/HelloWorld/Index.cshtml.

Altere o título e o elemento <h2> conforme realçado a seguir:

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

<h2>My Movie List</h2>

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

O título e o elemento <h2> são ligeiramente diferentes para que fique claro qual parte do código altera a exibição.

ViewData["Title"] = "Movie List"; no código acima define a propriedade Title do dicionário ViewData como “Lista de Filmes”. A propriedade Title é usada no elemento HTML <title> na página de layout:

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

Salve as alterações e navegue para https://localhost:{PORT}/HelloWorld.

Observe que as seguintes alterações foram feitas:

  • Título do navegador.
  • Título primário.
  • Títulos secundários.

Se não houver alterações no navegador, pode ser que o conteúdo que está sendo exibido esteja armazenado em cache. Pressione Ctrl+F5 no navegador para forçar a resposta do servidor a ser carregada. O título do navegador é criado com ViewData["Title"] que definimos no modelo de exibição Index.cshtml e o “- Aplicativo de Filme” adicionado no arquivo de layout.

O conteúdo do modelo de exibição Index.cshtml é mesclado com o modelo de exibição Views/Shared/_Layout.cshtml . Uma única resposta HTML é enviada ao navegador. Os modelos de layout facilitam a realização de alterações que se aplicam a todas as páginas de um aplicativo. Para saber mais, consulte Layout.

Exibição de Lista de Filmes

No entanto, a pequena quantidade de "dados", a mensagem "Olá aqui do nosso Modelo de Exibição!", é nativa do código. O aplicativo MVC tem um “V” (exibição), um “C” (controlador), mas ainda nenhum “M” (modelo).

Passando dados do controlador para a exibição

As ações do controlador são invocadas em resposta a uma solicitação de URL de entrada. Uma classe de controlador é o local em que o código é escrito e que manipula as solicitações recebidas do navegador. O controlador recupera dados de uma fonte de dados e decide qual tipo de resposta será enviada novamente para o navegador. Modelos de exibição podem ser usados em um controlador para gerar e formatar uma resposta HTML para o navegador.

Os controladores são responsáveis por fornecer os dados necessários para que um modelo de exibição renderize uma resposta.

Os modelos de exibição não devem:

  • Processar lógicas de negócios
  • Interagir diretamente com algum banco de dados.

O modelo de exibição deve funcionar somente com os dados fornecidos pelo controlador. Manter essa “separação de preocupações” ajuda a manter o código:

  • Limpo.
  • Testável.
  • Descomplicado em relação à manutenção.

Atualmente, o método Welcome na classe HelloWorldController usa um name e um parâmetro IDe, em seguida, gera os valores de saída diretamente no navegador.

Em vez de fazer com que o controlador renderize a resposta como uma cadeia de caracteres, altere o controlador para que ele use um modelo de exibição. O modelo de exibição gera uma resposta dinâmica, o que significa que é necessário passar os dados apropriados do controlador para a exibição para gerar a resposta. Faça isso fazendo com que o controlador coloque os dados dinâmicos (parâmetros) que o modelo de exibição precisa em um dicionário ViewData. O modelo de exibição pode então acessar os dados dinâmicos.

Em HelloWorldController.cs, altere o método Welcome para adicionar um valor Message e NumTimes ao dicionário ViewData.

O dicionário ViewData é um objeto dinâmico, o que significa que qualquer tipo pode ser usado. O objeto ViewData não tem propriedades definidas até que algo seja adicionado. O sistema de model binding do MVC mapeia automaticamente os parâmetros nomeados name e numTimes da cadeia de caracteres de consulta para os parâmetros do método. O HelloWorldController completo:

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();
        }
    }
}

O objeto de dicionário ViewData contém dados que serão passados para a exibição.

Criar um modelo de exibição de boas-vindas chamado Views/HelloWorld/Welcome.cshtml.

Você criará um loop no modelo de exibição Welcome.cshtml que exibe “Olá” NumTimes. Substitua o conteúdo de Views/HelloWorld/Welcome.cshtml pelo fornecido a seguir:

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

<h2>Welcome</h2>

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

Salve as alterações e navegue para a seguinte URL:

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

Os dados são obtidos da URL e passados para o controlador usando o associador de modelo MVC. O controlador empacota os dados em um dicionário ViewData e passa esse objeto para a exibição. Em seguida, a exibição renderiza os dados como HTML para o navegador.

Privacy exibição que mostra um rótulo de boas-vindas e a frase

No exemplo acima, o dicionário ViewData foi usado para passar dados do controlador para uma exibição. Mais adiante no tutorial, um modelo de exibição será usado para passar dados de um controlador para uma exibição. A abordagem do modelo de exibição para passar dados é geralmente a preferida em relação à abordagem do dicionário ViewData.

No próximo tutorial, será criado um banco de dados de filmes.