Transmitir dados para Exibir páginas mestras (VB)
pela Microsoft
O objetivo deste tutorial é explicar como você pode passar dados de um controlador para um modo de exibição master página. Examinamos duas estratégias para passar dados para uma página master de exibição. Primeiro, discutimos uma solução fácil que resulta em um aplicativo difícil de manter. Em seguida, examinamos uma solução muito melhor que requer um pouco mais de trabalho inicial, mas resulta em um aplicativo muito mais mantenedor.
Passando dados para exibir páginas mestras
O objetivo deste tutorial é explicar como você pode passar dados de um controlador para um modo de exibição master página. Examinamos duas estratégias para passar dados para uma página master de exibição. Primeiro, discutimos uma solução fácil que resulta em um aplicativo difícil de manter. Em seguida, examinamos uma solução muito melhor que requer um pouco mais de trabalho inicial, mas resulta em um aplicativo muito mais mantenedor.
O problema
Imagine que você está criando um aplicativo de banco de dados de filme e deseja exibir a lista de categorias de filmes em cada página do aplicativo (consulte a Figura 1). Imagine, além disso, que a lista de categorias de filmes é armazenada em uma tabela de banco de dados. Nesse caso, faria sentido recuperar as categorias do banco de dados e renderizar a lista de categorias de filme em uma exibição master página.
Figura 01: Exibindo categorias de filme em um modo de exibição master página (Clique para exibir imagem em tamanho real)
Este é o problema. Como recuperar a lista de categorias de filmes na página master? É tentador chamar métodos de suas classes de modelo diretamente na página master. Em outras palavras, é tentador incluir o código para recuperar os dados do banco de dados diretamente na página master. No entanto, ignorar seus controladores MVC para acessar o banco de dados violaria a separação limpo de preocupações que é um dos principais benefícios da criação de um aplicativo MVC.
Em um aplicativo MVC, você deseja que toda a interação entre as exibições do MVC e o modelo MVC seja tratada pelos controladores MVC. Essa separação de preocupações resulta em um aplicativo mais mantenedor, adaptável e testável.
Em um aplicativo MVC, todos os dados passados para uma exibição – incluindo uma exibição master página – devem ser passados para uma exibição por uma ação do controlador. Além disso, os dados devem ser passados aproveitando os dados de exibição. No restante deste tutorial, examinei dois métodos de passar dados de exibição para uma exibição master página.
A solução simples
Vamos começar com a solução mais simples para passar dados de exibição de um controlador para um modo de exibição master página. A solução mais simples é passar os dados de exibição para a página master em cada ação do controlador.
Considere o controlador na Listagem 1. Ele expõe duas ações denominadas Index()
e Details()
. O Index()
método de ação retorna todos os filmes na tabela de banco de dados Filmes. O Details()
método de ação retorna todos os filmes em uma categoria de filme específica.
Listagem 1 – Controllers\HomeController.vb
<HandleError()> _
Public Class HomeController
Inherits System.Web.Mvc.Controller
Private _dataContext As New MovieDataContext()
''' <summary>
''' Show list of all movies
''' </summary>
Function Index()
ViewData("categories") = From c In _dataContext.MovieCategories _
Select c
ViewData("movies") = From m In _dataContext.Movies _
Select m
Return View()
End Function
''' <summary>
''' Show list of movies in a category
''' </summary>
Function Details(ByVal id As Integer)
ViewData("categories") = From c In _dataContext.MovieCategories _
Select c
ViewData("movies") = From m In _dataContext.Movies _
Where m.CategoryId = id _
Select m
Return View()
End Function
End Class
Observe que as Index()
ações e Details()
adicionam dois itens para exibir dados. A Index()
ação adiciona duas chaves: categorias e filmes. A chave de categorias representa a lista de categorias de filme exibidas pela página master exibição. A chave de filmes representa a lista de filmes exibidos pela página exibição Índice.
A Details()
ação também adiciona duas chaves chamadas categorias e filmes. A chave de categorias, mais uma vez, representa a lista de categorias de filme exibidas pela página master exibição. A chave de filmes representa a lista de filmes em uma categoria específica exibida pela página exibição Detalhes (consulte a Figura 2).
Figura 02: a exibição Detalhes (Clique para exibir a imagem em tamanho real)
A exibição Índice está contida na Listagem 2. Ele simplesmente itera por meio da lista de filmes representados pelo item filmes em dados de exibição.
Listagem 2 – Views\Home\Index.aspx
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="MvcApplication1.Index" %>
<%@ Import Namespace="MvcApplication1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<ul>
<% For Each m In ViewData("movies")%>
<li><%= m.Title %></li>
<% Next%>
</ul>
</asp:Content>
A página master de exibição está contida na Listagem 3. O modo de exibição master página itera e renderiza todas as categorias de filme representadas pelo item de categorias dos dados de exibição.
Listagem 3 – Views\Shared\Site.master
<%@ Master Language="VB" AutoEventWireup="false" CodeBehind="Site.Master.vb" Inherits="MvcApplication1.Site" %>
<%@ Import Namespace="MvcApplication1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title></title>
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<div>
<h1>My Movie Website</h1>
<% For Each c In ViewData("categories")%>
<%=Html.ActionLink(c.Name, "Details", New With {.id = c.Id})%>
<% Next%>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</body>
</html>
Todos os dados são passados para a exibição e a exibição master página por meio de dados de exibição. Essa é a maneira correta de passar dados para a página master.
Então, o que há de errado com essa solução? O problema é que essa solução viola o princípio DRY (Don't Repeat Yourself). Cada ação do controlador deve adicionar a mesma lista de categorias de filme para exibir dados. Ter código duplicado em seu aplicativo torna seu aplicativo muito mais difícil de manter, adaptar e modificar.
A boa solução
Nesta seção, examinamos uma solução alternativa e melhor para passar dados de uma ação do controlador para uma exibição master página. Em vez de adicionar as categorias de filme para a página master em cada ação de controlador, adicionamos as categorias de filme aos dados de exibição apenas uma vez. Todos os dados de exibição usados pela página master de exibição são adicionados em um controlador de aplicativo.
A classe ApplicationController está contida na Listagem 4.
A classe ApplicationController está contida na Listagem 4.
Listagem 4 – Controllers\ApplicationController.vb
Public MustInherit Class ApplicationController
Inherits System.Web.Mvc.Controller
Private _dataContext As New MovieDataContext()
Public ReadOnly Property DataContext() As MovieDataContext
Get
Return _dataContext
End Get
End Property
Sub New()
ViewData("categories") = From c In DataContext.MovieCategories _
Select c
End Sub
End Class
Há três coisas que você deve observar sobre o controlador de aplicativo na Listagem 4. Primeiro, observe que a classe herda da classe base System.Web.Mvc.Controller. O controlador de aplicativo é uma classe de controlador.
Em segundo lugar, observe que a classe Controlador de aplicativo é uma classe MustInherit. Uma classe MustInherit é uma classe que deve ser implementada por uma classe concreta. Como o controlador de aplicativo é uma classe MustInherit, você não pode invocar nenhum método definido na classe diretamente. Se você tentar invocar a classe Application diretamente, receberá uma mensagem de erro Recurso Não Encontrado.
Em terceiro lugar, observe que o controlador de aplicativo contém um construtor que adiciona a lista de categorias de filme para exibir dados. Cada classe de controlador que herda do controlador de aplicativo chama o construtor do controlador de aplicativo automaticamente. Sempre que você chama qualquer ação em qualquer controlador herdado do controlador de aplicativo, as categorias de filme são incluídas nos dados de exibição automaticamente.
O controlador Filmes na Listagem 5 herda do controlador de aplicativo.
Listagem 5 – Controllers\MoviesController.vb
<HandleError()> _
Public Class MoviesController
Inherits ApplicationController
''' <summary>
''' Show list of all movies
''' </summary>
Function Index()
ViewData("movies") = From m In DataContext.Movies _
Select m
Return View()
End Function
''' <summary>
''' Show list of movies in a category
''' </summary>
Function Details(ByVal id As Integer)
ViewData("movies") = From m In DataContext.Movies _
Where m.CategoryId = id _
Select m
Return View()
End Function
End Class
O controlador Movies, assim como o controlador Home discutido na seção anterior, expõe dois métodos de ação chamados Index()
e Details()
. Observe que a lista de categorias de filme exibidas pelo modo de exibição master página não é adicionada para exibir dados no Index()
método ou Details()
. Como o controlador movies herda do controlador de aplicativo, a lista de categorias de filme é adicionada para exibir dados automaticamente.
Observe que essa solução para adicionar dados de exibição para uma exibição master página não viola o princípio DRY (Não Repita a Si mesmo). O código para adicionar a lista de categorias de filme para exibir dados está contido em apenas um local: o construtor do controlador de aplicativo.
Resumo
Neste tutorial, discutimos duas abordagens para passar dados de exibição de um controlador para um modo de exibição master página. Primeiro, examinamos uma abordagem simples, mas difícil de manter. Na primeira seção, discutimos como você pode adicionar dados de exibição para uma exibição master página em cada ação do controlador em seu aplicativo. Concluímos que essa era uma abordagem ruim porque viola o princípio DRY (Don't Repeat Yourself).
Em seguida, examinamos uma estratégia muito melhor para adicionar dados exigidos por um modo de exibição master página para exibir dados. Em vez de adicionar os dados de exibição em cada ação do controlador, adicionamos os dados de exibição apenas uma vez em um controlador de aplicativo. Dessa forma, você pode evitar código duplicado ao passar dados para uma página master de exibição em um aplicativo MVC ASP.NET.