Partilhar via


Criando um layout consistente em sites de Páginas da Web do ASP.NET (Razor)

por Tom FitzMacken

Este artigo explica como você pode usar páginas de layout em um site do Páginas da Web do ASP.NET (Razor) para criar blocos reutilizáveis de conteúdo (como cabeçalhos e rodapés) e criar uma aparência consistente para todas as páginas do site.

O que você aprenderá:

  • Como criar blocos reutilizáveis de conteúdo, como cabeçalhos e rodapés.
  • Como criar uma aparência consistente para todas as páginas em seu site usando um layout.
  • Como passar dados em tempo de execução para uma página de layout.

Estes são os ASP.NET recursos introduzidos no artigo:

  • Blocos de conteúdo, que são arquivos que contêm conteúdo formatado em HTML a ser inserido em várias páginas.
  • Páginas de layout, que são páginas que contêm conteúdo formatado em HTML que podem ser compartilhadas por páginas no site.
  • Os RenderPagemétodos , RenderBodye RenderSection , que informam ASP.NET onde inserir elementos de página.
  • O PageData dicionário que permite compartilhar dados entre blocos de conteúdo e páginas de layout.

Versões de software usadas no tutorial

  • Páginas da Web do ASP.NET (Razor) 3

Este tutorial também funciona com Páginas da Web do ASP.NET 2.

Sobre páginas de layout

Muitos sites têm conteúdo exibido em cada página, como um cabeçalho e rodapé, ou uma caixa que informa aos usuários que eles estão conectados. ASP.NET permite criar um arquivo separado com um bloco de conteúdo que pode conter texto, marcação e código, assim como uma página da Web normal. Em seguida, você pode inserir o bloco de conteúdo em outras páginas no site em que deseja que as informações apareçam. Dessa forma, você não precisa copiar e colar o mesmo conteúdo em todas as páginas. A criação de conteúdo comum como esse também facilita a atualização do seu site. Se você precisar alterar o conteúdo, basta atualizar um único arquivo e as alterações serão refletidas em todos os lugares em que o conteúdo foi inserido.

O diagrama a seguir mostra como os blocos de conteúdo funcionam. Quando um navegador solicita uma página do servidor Web, ASP.NET insere os blocos de conteúdo no ponto em que o RenderPage método é chamado na página main. A página concluída (mesclada) é enviada para o navegador.

Diagrama conceitual mostrando como o método RenderPage insere uma página referenciada na página atual.

Neste procedimento, você criará uma página que faz referência a dois blocos de conteúdo (um cabeçalho e um rodapé) localizados em arquivos separados. Você pode usar esses mesmos blocos de conteúdo em qualquer página do seu site. Quando terminar, você receberá uma página como esta:

Captura de tela mostrando uma página no navegador que resulta da execução de uma página que inclui chamadas para o método RenderPage.

  1. Na pasta raiz do seu site, crie um arquivo chamado Index.cshtml.

  2. Substitua a marcação existente pelo seguinte:

    <!DOCTYPE html>
    <html>
      <head>
        <title>Main Page</title>
      </head>
      <body>
    
        <h1>Index Page Content</h1>
        <p>This is the content of the main page.</p>
    
      </body>
    </html>
    
  3. Na pasta raiz, crie uma pasta chamada Compartilhado.

    Observação

    É uma prática comum armazenar arquivos que são compartilhados entre páginas da Web em uma pasta chamada Compartilhado.

  4. Na pasta Compartilhado , crie um arquivo chamado _Header.cshtml.

  5. Substitua qualquer conteúdo existente pelo seguinte:

    <div class="header">This is header text.</div>
    

    Observe que o nome do arquivo é _Header.cshtml, com um sublinhado (_) como prefixo. ASP.NET não enviará uma página para o navegador se seu nome começar com um sublinhado. Isso impede que as pessoas solicitem (inadvertidamente ou não) essas páginas diretamente. É uma boa ideia usar um sublinhado para nomear páginas que têm blocos de conteúdo, porque você realmente não quer que os usuários possam solicitar essas páginas — elas existem estritamente para serem inseridas em outras páginas.

  6. Na pasta Compartilhado , crie um arquivo chamado _Footer.cshtml e substitua o conteúdo pelo seguinte:

    <div class="footer">&copy; 2012 Contoso Pharmaceuticals. All rights reserved.
    </div>
    
  7. Na página Index.cshtml , adicione duas chamadas ao RenderPage método , conforme mostrado aqui:

    <!DOCTYPE html>
    <html>
      <head>
        <title>Main Page</title>
      </head>
      <body>
    
        @RenderPage("~/Shared/_Header.cshtml")
    
        <h1>Index Page Content</h1>
        <p>This is the content of the main page.</p>
    
        @RenderPage("~/Shared/_Footer.cshtml")
    
      </body>
    </html>
    

    Isso mostra como inserir um bloco de conteúdo em uma página da Web. Chame o RenderPage método e passe o nome do arquivo cujo conteúdo você deseja inserir nesse ponto. Aqui, você está inserindo o conteúdo dos arquivos _Header.cshtml e _Footer.cshtml no arquivo Index.cshtml .

  8. Execute a página Index.cshtml em um navegador. (No WebMatrix, no workspace Arquivos , clique com o botão direito do mouse no arquivo e selecione Iniciar no navegador.)

  9. No navegador, exiba a origem da página. (Por exemplo, na Internet Explorer, clique com o botão direito do mouse na página e clique em Exibir Fonte.)

    Isso permite que você veja a marcação de página da Web enviada para o navegador, que combina a marcação de página de índice com os blocos de conteúdo. O exemplo a seguir mostra a origem da página renderizada para Index.cshtml. As chamadas para RenderPage que você inseriu em Index.cshtml foram substituídas pelo conteúdo real dos arquivos de cabeçalho e rodapé.

    <!DOCTYPE html>
    <html>
      <head>
        <title>Main Page</title>
      </head>
      <body>
    
      <div class="header">
        This is header text.
      </div>
    
        <h1>Index Page Content</h1>
        <p>This is the content of the main page.</p>
    
      <div class="footer">
        &copy; 2012 Contoso Pharmaceuticals. All rights reserved.
      </div>
    
      </body>
    </html>
    

Criando uma aparência consistente usando páginas de layout

Até agora, você viu que é fácil incluir o mesmo conteúdo em várias páginas. Uma abordagem mais estruturada para criar uma aparência consistente para um site é usar páginas de layout. Uma página de layout define a estrutura de uma página da Web, mas não contém nenhum conteúdo real. Depois de criar uma página de layout, você pode criar páginas da Web que contêm o conteúdo e vinculá-las à página de layout. Quando essas páginas forem exibidas, elas serão formatadas de acordo com a página de layout. (Nesse sentido, uma página de layout atua como um tipo de modelo para conteúdo definido em outras páginas.)

A página de layout é como qualquer página HTML, exceto que ela contém uma chamada para o RenderBody método . A posição do RenderBody método na página de layout determina onde as informações da página de conteúdo serão incluídas.

O diagrama a seguir mostra como páginas de conteúdo e páginas de layout são combinadas em tempo de execução para produzir a página da Web concluída. O navegador solicita uma página de conteúdo. A página de conteúdo tem código que especifica a página de layout a ser usada para a estrutura da página. Na página de layout, o conteúdo é inserido no ponto em que o RenderBody método é chamado. Os blocos de conteúdo também podem ser inseridos na página de layout chamando o RenderPage método , como você fez na seção anterior. Quando a página da Web é concluída, ela é enviada para o navegador.

Captura de tela mostrando uma página no navegador que resulta da execução de uma página que inclui chamadas para o método RenderBody.

O procedimento a seguir mostra como criar uma página de layout e vincular páginas de conteúdo a ela.

  1. Na pasta Compartilhado do seu site, crie um arquivo chamado _Layout1.cshtml.

  2. Substitua qualquer conteúdo existente pelo seguinte:

    <!DOCTYPE html>
    <html>
      <head>
        <title>Structured Content </title>
        <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
      </head>
      <body>
        @RenderPage("~/Shared/_Header2.cshtml")
        <div id="main">
          @RenderBody()
        </div>
        <div id="footer">
          &copy; 2012 Contoso Pharmaceuticals. All rights reserved.
        </div>
      </body>
    </html>
    

    Use o RenderPage método em uma página de layout para inserir blocos de conteúdo. Uma página de layout pode conter apenas uma chamada para o RenderBody método .

  3. Na pasta Compartilhado , crie um arquivo chamado _Header2.cshtml e substitua qualquer conteúdo existente pelo seguinte:

    <div id="header">Creating a Consistent Look</div>
    
  4. Na pasta raiz, crie uma nova pasta e nomeie-a como Estilos.

  5. Na pasta Estilos , crie um arquivo chamado Site.css e adicione as seguintes definições de estilo:

    h1 {
        border-bottom: 3px solid #cc9900;
        font: 2.75em/1.75em Georgia, serif;
        color: #996600;
    }
    
    ul {
        list-style-type: none;
    }
    
    body {
        margin: 0;
        padding: 1em;
        background-color: #ffffff;
        font: 75%/1.75em "Trebuchet MS", Verdana, sans-serif;
        color: #006600;
    }
    
    #list {
        margin: 1em 0 7em -3em;
        padding: 1em 0 0 0;
        background-color: #ffffff;
        color: #996600;
        width: 25%;
        float: left;
    }
    
    #header, #footer {
        margin: 0;
        padding: 0;
        color: #996600;
    }
    

    Essas definições de estilo estão aqui apenas para mostrar como as folhas de estilos podem ser usadas com páginas de layout. Se desejar, você pode definir seus próprios estilos para esses elementos.

  6. Na pasta raiz, crie um arquivo chamado Content1.cshtml e substitua qualquer conteúdo existente pelo seguinte:

    @{
        Layout = "~/Shared/_Layout1.cshtml";
    }
    
    <h1> Structured Content </h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
    nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.</p>
    

    Esta é uma página que usará uma página de layout. O bloco de código na parte superior da página indica qual página de layout usar para formatar esse conteúdo.

  7. Execute Content1.cshtml em um navegador. A página renderizada usa o formato e a folha de estilos definidos em _Layout1.cshtml e o texto (conteúdo) definido em Content1.cshtml.

    [A captura de tela mostra a execução do CSHTML de ponto de Conteúdo 1 em um navegador.]

    Você pode repetir a etapa 6 para criar páginas de conteúdo adicionais que podem compartilhar a mesma página de layout.

    Observação

    Você pode configurar seu site para que possa usar automaticamente a mesma página de layout para todas as páginas de conteúdo em uma pasta. Para obter detalhes, consulte Personalizando o comportamento de Site-Wide para Páginas da Web do ASP.NET.

Criando páginas de layout que têm várias seções de conteúdo

Uma página de conteúdo pode ter várias seções, o que é útil se você quiser usar layouts que tenham várias áreas com conteúdo substituível. Na página de conteúdo, você atribui um nome exclusivo a cada seção. (A seção padrão é deixada sem nome.) Na página de layout, você adiciona um RenderBody método para especificar onde a seção sem nome (padrão) deve aparecer. Em seguida, você adiciona métodos separados RenderSection para renderizar seções nomeadas individualmente.

O diagrama a seguir mostra como ASP.NET lida com o conteúdo dividido em várias seções. Cada seção nomeada está contida em um bloco de seção na página de conteúdo. (Eles são nomeados Header e List no exemplo.) A estrutura insere a seção de conteúdo na página de layout no ponto em que o RenderSection método é chamado. A seção sem nome (padrão) é inserida no ponto em que o RenderBody método é chamado, como você viu anteriormente.

Diagrama conceitual mostrando como o método RenderSection insere seções de referências na página atual.

Este procedimento mostra como criar uma página de conteúdo que tem várias seções de conteúdo e como renderizá-la usando uma página de layout que dá suporte a várias seções de conteúdo.

  1. Na pasta Compartilhado , crie um arquivo chamado _Layout2.cshtml.

  2. Substitua qualquer conteúdo existente pelo seguinte:

    <!DOCTYPE html>
    <html>
      <head>
        <title>Multisection Content</title>
        <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
      </head>
      <body>
        <div id="header">
          @RenderSection("header")
        </div>
        <div id="list">
          @RenderSection("list")
        </div>
        <div id="main">
          @RenderBody()
        </div>
        <div id="footer">
          &copy; 2012 Contoso Pharmaceuticals. All rights reserved.
        </div>
      </body>
    </html>
    

    Use o RenderSection método para renderizar as seções de cabeçalho e lista.

  3. Na pasta raiz, crie um arquivo chamado Content2.cshtml e substitua qualquer conteúdo existente pelo seguinte:

    @{
        Layout = "~/Shared/_Layout2.cshtml";
    }
    
    @section header {
        <div id="header">
            Creating a Consistent Look
        </div>
    }
    
    @section list {
        <ul>
            <li>Lorem</li>
            <li>Ipsum</li>
            <li>Dolor</li>
            <li>Consecte</li>
            <li>Eiusmod</li>
            <li>Tempor</li>
            <li>Incididu</li>
        </ul>
    }
    
    <h1>Multisection Content</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
    nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.</p>
    

    Esta página de conteúdo contém um bloco de código na parte superior da página. Cada seção nomeada está contida em um bloco de seção. O restante da página contém a seção de conteúdo padrão (sem nome).

  4. Execute Content2.cshtml em um navegador.

    Captura de tela mostrando uma página no navegador que resulta da execução de uma página que inclui chamadas para o método RenderSection.

Tornando as seções de conteúdo opcionais

Normalmente, as seções criadas em uma página de conteúdo precisam corresponder às seções definidas na página de layout. Você poderá receber erros se qualquer um dos seguintes itens ocorrer:

  • A página de conteúdo contém uma seção que não tem nenhuma seção correspondente na página de layout.
  • A página de layout contém uma seção para a qual não há conteúdo.
  • A página de layout inclui chamadas de método que tentam renderizar a mesma seção mais de uma vez.

No entanto, você pode substituir esse comportamento para uma seção nomeada declarando a seção como opcional na página de layout. Isso permite definir várias páginas de conteúdo que podem compartilhar uma página de layout, mas que podem ou não ter conteúdo para uma seção específica.

  1. Abra Content2.cshtml e remova a seguinte seção:

    @section header {
      <div id="header">
        Creating a Consistent Look
      </div>
    }
    
  2. Salve a página e execute-a em um navegador. Uma mensagem de erro é exibida porque a página de conteúdo não fornece conteúdo para uma seção definida na página de layout, ou seja, a seção de cabeçalho.

    Captura de tela que mostra o erro que ocorre se você executar uma página que chama o método RenderSection, mas a seção correspondente não é fornecida.

  3. Na pasta Compartilhado , abra a página _Layout2.cshtml e substitua esta linha:

    @RenderSection("header")
    

    pelo código a seguir:

    @RenderSection("header", required: false)
    

    Como alternativa, você pode substituir a linha de código anterior pelo seguinte bloco de código, que produz os mesmos resultados:

    @if (IsSectionDefined("header")) {
        @RenderSection("header")
    }
    
  4. Execute a página Content2.cshtml em um navegador novamente. (Se você ainda tiver essa página aberta no navegador, basta atualizá-la.) Desta vez, a página é exibida sem erro, mesmo que não tenha cabeçalho.

Passando dados para páginas de layout

Você pode ter dados definidos na página de conteúdo que você precisa consultar em uma página de layout. Nesse caso, você precisa passar os dados da página de conteúdo para a página de layout. Por exemplo, talvez você queira exibir o status de logon de um usuário ou pode querer mostrar ou ocultar áreas de conteúdo com base na entrada do usuário.

Para passar dados de uma página de conteúdo para uma página de layout, você pode colocar valores na PageData propriedade da página de conteúdo. A PageData propriedade é uma coleção de pares nome/valor que contém os dados que você deseja passar entre páginas. Na página de layout, você pode ler valores fora da PageData propriedade .

Aqui está outro diagrama. Este mostra como ASP.NET pode usar a PageData propriedade para passar valores de uma página de conteúdo para a página de layout. Quando ASP.NET começa a criar a página da Web, ela cria a PageData coleção. Na página de conteúdo, você escreve código para colocar dados na PageData coleção. Os valores na PageData coleção também podem ser acessados por outras seções na página de conteúdo ou por blocos de conteúdo adicionais.

Diagrama conceitual que mostra como uma página de conteúdo pode preencher um dicionário PageData e passar essas informações para a página de layout.

O procedimento a seguir mostra como passar dados de uma página de conteúdo para uma página de layout. Quando a página é executada, ela exibe um botão que permite que o usuário oculte ou mostre uma lista definida na página de layout. Quando os usuários clicam no botão, ele define um valor verdadeiro/falso (booliano) na PageData propriedade . A página de layout lê esse valor e, se for falso, oculta a lista. O valor também é usado na página de conteúdo para determinar se o botão Ocultar Lista ou Mostrar Lista deve ser exibido.

[Captura de tela que mostra a página Passando Dados.]

  1. Na pasta raiz, crie um arquivo chamado Content3.cshtml e substitua qualquer conteúdo existente pelo seguinte:

    @{
        Layout = "~/Shared/_Layout3.cshtml";
    
        PageData["Title"] = "Passing Data";
        PageData["ShowList"] = true;
    
        if (IsPost) {
            if (Request.Form["list"] == "off") {
                PageData["ShowList"] = false;
            }
        }
    }
    
    @section header {
      <div id="header">
        Creating a Consistent Look
      </div>
    }
    
    <h1>@PageData["Title"]</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
    nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.</p>
    
    @if (PageData["ShowList"] == true) {
        <form method="post" action="">
          <input type="hidden" name="list" value="off" />
          <input type="submit" value="Hide List" />
        </form>
    }
    else {
        <form method="post" action="">
          <input type="hidden" name="list" value="on" />
          <input type="submit" value="Show List" />
        </form>
    }
    

    O código armazena duas partes de dados na PageData propriedade : o título da página da Web e true ou false para especificar se uma lista deve ser exibida.

    Observe que ASP.NET permite colocar a marcação HTML na página condicionalmente usando um bloco de código. Por exemplo, o if/else bloco no corpo da página determina qual formulário exibir dependendo se está definido como PageData["ShowList"] true.

  2. Na pasta Compartilhado , crie um arquivo chamado _Layout3.cshtml e substitua qualquer conteúdo existente pelo seguinte:

    <!DOCTYPE html>
    <html>
      <head>
        <title>@PageData["Title"]</title>
        <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
      </head>
      <body>
        <div id="header">
          @RenderSection("header")
        </div>
          @if (PageData["ShowList"] == true) {
              <div id="list">
                @RenderPage("~/Shared/_List.cshtml")
              </div>
          }
        <div id="main">
          @RenderBody()
        </div>
        <div id="footer">
          <p>&copy; 2012 Contoso Pharmaceuticals. All rights reserved.</p>
        </div>
      </body>
    </html>
    

    A página de layout inclui uma expressão no <title> elemento que obtém o valor do título da PageData propriedade . Ele também usa o ShowList valor da PageData propriedade para determinar se o bloco de conteúdo da lista deve ser exibido.

  3. Na pasta Compartilhado , crie um arquivo chamado _List.cshtml e substitua qualquer conteúdo existente pelo seguinte:

    <ul>
      <li>Lorem</li>
      <li>Ipsum</li>
      <li>Dolor</li>
      <li>Consecte</li>
      <li>Eiusmod</li>
      <li>Tempor</li>
      <li>Incididu</li>
    </ul>
    
  4. Execute a página Content3.cshtml em um navegador. A página é exibida com a lista visível no lado esquerdo da página e um botão Ocultar Lista na parte inferior.

    Captura de tela mostrando a página que inclui a lista e um botão que diz

  5. Clique em Ocultar Lista. A lista desaparece e o botão é alterado para Mostrar Lista.

    Captura de tela mostrando a página que não inclui a lista e um botão que diz

  6. Clique no botão Mostrar Lista e a lista será exibida novamente.

Recursos adicionais

Personalizando o comportamento de Site-Wide para Páginas da Web do ASP.NET