Exibições no ASP.NET Core MVC
Por Steve Smith e Dave Brock
Este documento explica as exibições usadas em aplicativos do ASP.NET Core MVC. Para obter informações sobre páginas Razor, consulte Introdução às Páginas Razor no ASP.NET Core.
No padrão MVC (Modelo-Exibição-Controlador), a exibição cuida da apresentação de dados do aplicativo e da interação com o usuário. Uma exibição é um modelo HTML com marcação Razor inserida. A marcação Razor é um código que interage com a marcação HTML para produzir uma página da Web que é enviada ao cliente.
No MVC do ASP.NET Core, as exibições são arquivos .cshtml
que usam a linguagem de programação C# na marcação Razor. Geralmente, arquivos de exibição são agrupados em pastas nomeadas para cada um dos controladores do aplicativo. As pastas são armazenadas em uma pasta Views
na raiz do aplicativo:
O controlador Home
é representado por uma pasta Home
dentro da pasta Views
. A pasta Home
contém as exibições das páginas da Web About
, Contact
e Index
(página inicial). Quando um usuário solicita uma dessas três páginas da Web, ações do controlador no controlador Home
determinam qual das três exibições é usada para compilar e retornar uma página da Web para o usuário.
Use layouts para fornecer seções de páginas da Web consistentes e reduzir repetições de código. Layouts geralmente contêm o cabeçalho, elementos de navegação e menu e o rodapé. O cabeçalho e o rodapé geralmente contêm marcações repetitivas para muitos elementos de metadados, bem como links para ativos de script e estilo. Layouts ajudam a evitar essa marcação repetitiva em suas exibições.
Exibições parciais reduzem a duplicação de código gerenciando as partes reutilizáveis das exibições. Por exemplo, uma exibição parcial é útil para uma biografia do autor que aparece em várias exibições em um site de blog. Uma biografia do autor é um conteúdo de exibição comum e não requer que um código seja executado para produzi-lo para a página da Web. O conteúdo da biografia do autor é disponibilizado para a exibição usando somente o model binding, de modo que usar uma exibição parcial para esse tipo de conteúdo é ideal.
Componentes de exibição são semelhantes a exibições parciais no sentido em que permitem reduzir códigos repetitivos, mas são adequados para conteúdos de exibição que requerem que um código seja executado no servidor para renderizar a página da Web. Componentes de exibição são úteis quando o conteúdo renderizado requer uma interação com o banco de dados, como para o carrinho de compras de um site. Os componentes de exibição não ficam limitados ao model binding para produzir a saída da página da Web.
Benefícios do uso de exibições
As exibições ajudam a estabelecer uma separação de Interesses dentro de um aplicativo MVC, separando a marcação da interface do usuário de outras partes do aplicativo. Seguir um design de SoC faz com que seu aplicativo seja modular, o que fornece vários benefícios:
- A manutenção do aplicativo é mais fácil, porque ele é melhor organizado. Geralmente, as exibições são agrupadas segundo os recursos do aplicativo. Isso facilita encontrar exibições relacionadas ao trabalhar em um recurso.
- As partes do aplicativo ficam acopladas de forma flexível. Você pode compilar e atualizar as exibições do aplicativo separadamente da lógica de negócios e dos componentes de acesso a dados. É possível modificar os modos de exibição do aplicativo sem precisar necessariamente atualizar outras partes do aplicativo.
- É mais fácil testar as partes da interface do usuário do aplicativo porque as exibições são unidades separadas.
- Devido à melhor organização, é menos provável que você repita acidentalmente seções da interface do usuário.
Criando uma exibição
As exibições específicas a um controlador são criadas na pasta Views/[ControllerName]
. As exibições que são compartilhadas entre controladores são colocadas na pasta Views/Shared
. Para criar uma exibição, adicione um novo arquivo e dê a ele o mesmo nome que o da ação de seu controlador associado, com a extensão de arquivo .cshtml
. Para criar uma exibição que corresponda à ação About
no controlador Home
, crie um arquivo About.cshtml
na pasta Views/Home
:
@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<p>Use this area to provide additional information.</p>
A marcação Razor começa com o símbolo @
. Execute instruções em C# colocando o código C# dentro de blocos de código Razor entre chaves ({ ... }
). Por exemplo, consulte a atribuição de "About" para ViewData["Title"]
mostrado acima. É possível exibir valores em HTML simplesmente referenciando o valor com o símbolo @
. Veja o conteúdo dos elementos <h2>
e <h3>
acima.
O conteúdo da exibição mostrado acima é apenas uma parte da página da Web inteira que é renderizada para o usuário. O rest do layout da página e outros aspectos comuns da exibição são especificados em outros arquivos de exibição. Para saber mais, consulte o tópico sobre Layout.
Como controladores especificam exibições
As exibições normalmente são retornadas de ações como ViewResult, que é um tipo de ActionResult. O método de ação pode criar e retornar um ViewResult
diretamente, mas normalmente isso não é feito. Como a maioria dos controladores herda de Controller, basta usar o método auxiliar View
para retornar o ViewResult
:
HomeController.cs
:
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
Quando essa ação é retornada, a exibição About.cshtml
mostrada na seção anterior é renderizada como a seguinte página da Web:
O método auxiliar View
tem várias sobrecargas. Opcionalmente, você pode especificar:
Uma exibição explícita a ser retornada:
return View("Orders");
Um modelo a ser passado para a exibição:
return View(Orders);
Um modo de exibição e um modelo:
return View("Orders", Orders);
Descoberta de exibição
Quando uma ação retorna uma exibição, um processo chamado descoberta de exibição ocorre. Esse processo determina qual arquivo de exibição é usado com base no nome da exibição.
O comportamento padrão do método View
(return View();
) é retornar uma exibição com o mesmo nome que o método de ação do qual ela é chamada. Por exemplo, o nome do método About
ActionResult
do controlador é usado para pesquisar um arquivo de exibição chamado About.cshtml
. Primeiro, o runtime procura a exibição na pasta Views/[ControllerName]
. Se não encontrar uma exibição correspondente nela, ele procura pela exibição na pasta Shared
.
Não importa se você retornar implicitamente o ViewResult
com return View();
ou se passar explicitamente o nome de exibição para o método View
com return View("<ViewName>");
. Nos dois casos, a descoberta de exibição pesquisa por um arquivo de exibição correspondente nesta ordem:
Views/\[ControllerName]/\[ViewName].cshtml
Views/Shared/\[ViewName].cshtml
Um caminho de arquivo de exibição pode ser fornecido em vez de um nome de exibição. Se um caminho absoluto que começa na raiz do aplicativo (ou é iniciado por "/" ou "~ /") estiver sendo usado, a extensão .cshtml
deverá ser especificada:
return View("Views/Home/About.cshtml");
Você também pode usar um caminho relativo para especificar exibições em diretórios diferentes sem a extensão .cshtml
. Dentro do HomeController
, você pode retornar a exibição Index
de suas exibições Manage
com um caminho relativo:
return View("../Manage/Index");
De forma semelhante, você pode indicar o atual diretório específico do controlador com o prefixo ". /":
return View("./About");
Exibições parciais e componentes de exibição usam mecanismos de descoberta semelhantes (mas não idênticos).
É possível personalizar a convenção padrão de como as exibições ficam localizadas dentro do aplicativo usando um IViewLocationExpander personalizado.
A descoberta de exibição depende da localização de arquivos de exibição pelo nome do arquivo. Se o sistema de arquivos subjacente diferenciar maiúsculas de minúsculas, os nomes de exibição provavelmente diferenciarão maiúsculas de minúsculas. Para fins de compatibilidade de sistemas operacionais, padronize as maiúsculas e minúsculas dos nomes de controladores e de ações e dos nomes de arquivos e pastas de exibição. Se encontrar um erro indicando que não é possível encontrar um arquivo de exibição ao trabalhar com um sistema de arquivos que diferencia maiúsculas de minúsculas, confirme que o uso de maiúsculas e minúsculas é correspondente entre o arquivo de exibição solicitado e o nome do arquivo de exibição real.
Siga a melhor prática de organizar a estrutura de arquivos de suas exibições de forma a refletir as relações entre controladores, ações e exibições para facilidade de manutenção e clareza.
Passar dados para exibições
Passe dados para exibições usando várias abordagens:
- Dados fortemente tipados: viewmodel
- Dados fracamente tipados
ViewData
(ViewDataAttribute
)ViewBag
Dados fortemente tipados (viewmodel)
A abordagem mais robusta é especificar um tipo de modelo na exibição. Esse modelo é conhecido como viewmodel. Você passa uma instância do tipo viewmodel para a exibição da ação.
Usar um viewmodel para passar dados para uma exibição permite que a exibição tire proveito da verificação de tipo forte. Tipagem forte (ou fortemente tipado) significa que cada variável e constante têm um tipo definido explicitamente (por exemplo, string
, int
ou DateTime
). A validade dos tipos usados em uma exibição é verificada em tempo de compilação.
O Visual Studio e o Visual Studio Code listam membros de classe fortemente tipados usando um recurso chamado IntelliSense. Quando quiser ver as propriedades de um viewmodel, digite o nome da variável para o viewmodel, seguido por um ponto final (.
). Isso ajuda você a escrever código mais rapidamente e com menos erros.
Especifique um modelo usando a diretiva @model
. Use o modelo com @Model
:
@model WebApplication1.ViewModels.Address
<h2>Contact</h2>
<address>
@Model.Street<br>
@Model.City, @Model.State @Model.PostalCode<br>
<abbr title="Phone">P:</abbr> 425.555.0100
</address>
Para fornecer o modelo à exibição, o controlador o passa como um parâmetro:
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
var viewModel = new Address()
{
Name = "Microsoft",
Street = "One Microsoft Way",
City = "Redmond",
State = "WA",
PostalCode = "98052-6399"
};
return View(viewModel);
}
Não há restrições quanto aos tipos de modelo que você pode fornecer a uma exibição. Recomendamos o uso de viewmodels do tipo POCO (objeto CRL básico) com pouco ou nenhum comportamento (métodos) definido. Geralmente, classes de viewmodel são armazenadas na pasta Models
ou em uma pasta ViewModels
separada na raiz do aplicativo. O viewmodel Address
usado no exemplo acima é um viewmodel POCO armazenado em um arquivo chamado Address.cs
:
namespace WebApplication1.ViewModels
{
public class Address
{
public string Name { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
}
}
Nada impede que você use as mesmas classes para seus tipos de viewmodel e seus tipos de modelo de negócios. No entanto, o uso de modelos separados permite que suas exibições variem independentemente das partes de lógica de negócios e de acesso a dados do aplicativo. A separação de modelos e viewmodels também oferece benefícios de segurança quando os modelos usam model binding e validação para dados enviados ao aplicativo pelo usuário.
Dados com tipo fraco (ViewData
, atributo [ViewData]
e ViewBag
)
ViewBag
não está disponível por padrão para uso em Razor Pages classes PageModel
.
Além de exibições fortemente tipadas, as exibições têm acesso a uma coleção de dados fracamente tipados (também chamada de tipagem flexível). Diferente dos tipos fortes, ter tipos fracos (ou tipos flexíveis) significa que você não declara explicitamente o tipo dos dados que está usando. Você pode usar a coleção de dados fracamente tipados para transmitir pequenas quantidades de dados para dentro e para fora dos controladores e das exibições.
Passar dados entre... | Exemplo |
---|---|
Um controlador e uma exibição | Preencher uma lista suspensa com os dados. |
Uma exibição e uma exibição de layout | Definir o conteúdo do elemento <title> na exibição de layout de um arquivo de exibição. |
Uma exibição parcial e uma exibição | Um widget que exibe dados com base na página da Web que o usuário solicitou. |
Essa coleção pode ser referenciada por meio das propriedades ViewData
ou ViewBag
em controladores e exibições. A propriedade ViewData
é um dicionário de objetos fracamente tipados. A propriedade ViewBag
é um wrapper em torno de ViewData
que fornece propriedades dinâmicas à coleção de ViewData
subjacente. Observação: as pesquisas de chave diferenciam maiúsculas de minúsculas tanto para ViewData
quanto para ViewBag
.
ViewData
e ViewBag
são resolvidos dinamicamente em runtime. Uma vez que não oferecem verificação de tipo em tempo de compilação, geralmente ambos são mais propensos a erros do que quando um viewmodel é usado. Por esse motivo, alguns desenvolvedores preferem nunca usar ViewData
e ViewBag
ou usá-los o mínimo possível.
ViewData
ViewData
é um objeto ViewDataDictionary acessado por meio de chaves string
. Dados de cadeias de caracteres podem ser armazenados e usados diretamente, sem a necessidade de conversão, mas você precisa converter os valores de outros objetos ViewData
em tipos específicos quando extraí-los. Você pode usar ViewData
para passar dados de controladores para exibições e dentro das exibições, incluindo exibições parciais e layouts.
A seguir, temos um exemplo que define valores para uma saudação e um endereço usando ViewData
em uma ação:
public IActionResult SomeAction()
{
ViewData["Greeting"] = "Hello";
ViewData["Address"] = new Address()
{
Name = "Steve",
Street = "123 Main St",
City = "Hudson",
State = "OH",
PostalCode = "44236"
};
return View();
}
Trabalhar com os dados em uma exibição:
@{
// Since Address isn't a string, it requires a cast.
var address = ViewData["Address"] as Address;
}
@ViewData["Greeting"] World!
<address>
@address.Name<br>
@address.Street<br>
@address.City, @address.State @address.PostalCode
</address>
Atributo [ViewData]
Outra abordagem que usa ViewDataDictionary é ViewDataAttribute. As propriedades nos controladores ou nos modelos da Página Razor marcadas com o atributo [ViewData]
têm seus valores armazenados e carregados do dicionário.
No exemplo a seguir, o controlador Home contém uma propriedade Title
marcada com [ViewData]
. O método About
define o título para a exibição About:
public class HomeController : Controller
{
[ViewData]
public string Title { get; set; }
public IActionResult About()
{
Title = "About Us";
ViewData["Message"] = "Your application description page.";
return View();
}
}
No layout, o título é lido a partir do dicionário ViewData:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"] - WebApplication</title>
...
ViewBag
ViewBag
não está disponível por padrão para uso em Razor Pages classes PageModel
.
ViewBag
é um objeto Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData
que fornece acesso dinâmico aos objetos armazenados em ViewData
. Pode ser mais conveniente trabalhar com ViewBag
, pois ele não requer uma conversão. O exemplo a seguir mostra como usar ViewBag
com o mesmo resultado que o uso de ViewData
acima:
public IActionResult SomeAction()
{
ViewBag.Greeting = "Hello";
ViewBag.Address = new Address()
{
Name = "Steve",
Street = "123 Main St",
City = "Hudson",
State = "OH",
PostalCode = "44236"
};
return View();
}
@ViewBag.Greeting World!
<address>
@ViewBag.Address.Name<br>
@ViewBag.Address.Street<br>
@ViewBag.Address.City, @ViewBag.Address.State @ViewBag.Address.PostalCode
</address>
Usando ViewData
e ViewBag
simultaneamente
ViewBag
não está disponível por padrão para uso em Razor Pages classes PageModel
.
Como ViewData
e ViewBag
fazem referência à mesma coleção ViewData
subjacente, você pode usar ViewData
e ViewBag
, além de misturá-los e combiná-los ao ler e gravar valores.
Defina o título usando ViewBag
e a descrição usando ViewData
na parte superior de uma exibição About.cshtml
:
@{
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "About Contoso";
ViewData["Description"] = "Let us tell you about Contoso's philosophy and mission.";
}
Leia as propriedades, mas inverta o uso de ViewData
e ViewBag
. No arquivo _Layout.cshtml
, obtenha o título usando ViewData
e a descrição usando ViewBag
:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"]</title>
<meta name="description" content="@ViewBag.Description">
...
Lembre-se de que cadeias de caracteres não exigem uma conversão para ViewData
. Você pode usar @ViewData["Title"]
sem converter.
Usar ViewData
e ViewBag
ao mesmo tempo funciona, assim como misturar e combinar e leitura e a gravação das propriedades. A seguinte marcação é renderizada:
<!DOCTYPE html>
<html lang="en">
<head>
<title>About Contoso</title>
<meta name="description" content="Let us tell you about Contoso's philosophy and mission.">
...
Resumo das diferenças entre ViewData
e ViewBag
ViewBag
não está disponível por padrão para uso em Razor Pages classes PageModel
.
ViewData
- Deriva de ViewDataDictionary, de forma que tem propriedades de dicionário que podem ser úteis, como
ContainsKey
,Add
,Remove
eClear
. - Chaves no dicionário são cadeias de caracteres, de forma que espaços em branco são permitidos. Exemplo:
ViewData["Some Key With Whitespace"]
- Qualquer tipo diferente de
string
deve ser convertido na exibição para usarViewData
.
- Deriva de ViewDataDictionary, de forma que tem propriedades de dicionário que podem ser úteis, como
ViewBag
- Deriva de
Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData
, de forma que permite a criação de propriedades dinâmicas usando a notação de ponto (@ViewBag.SomeKey = <value or object>
) e nenhuma conversão é necessária. A sintaxe deViewBag
torna mais rápido adicioná-lo a controladores e exibições. - Mais simples de verificar quanto à presença de valores nulos. Exemplo:
@ViewBag.Person?.Name
- Deriva de
Quando usar ViewData
ou ViewBag
ViewData
e ViewBag
são abordagens igualmente válidas para passar pequenas quantidades de dados entre controladores e exibições. A escolha de qual delas usar é baseada na preferência. Você pode misturar e combinar objetos ViewData
e ViewBag
, mas é mais fácil ler e manter o código quando uma abordagem é usada de maneira consistente. Ambas as abordagens são resolvidas dinamicamente em runtime e, portanto, são propensas a causar erros de runtime. Algumas equipes de desenvolvimento as evitam.
Exibições dinâmicas
Exibições que não declaram um tipo de modelo usando @model
, mas que têm uma instância de modelo passada a elas (por exemplo, return View(Address);
) podem referenciar as propriedades da instância dinamicamente:
<address>
@Model.Street<br>
@Model.City, @Model.State @Model.PostalCode<br>
<abbr title="Phone">P:</abbr> 425.555.0100
</address>
Esse recurso oferece flexibilidade, mas não oferece proteção de compilação ou IntelliSense. Se a propriedade não existir, a geração da página da Web falhará em runtime.
Mais recursos das exibições
Auxiliares de Marca facilitam a adição do comportamento do lado do servidor às marcações HTML existentes. O uso de Auxiliares de marca evita a necessidade de escrever código personalizado ou auxiliares em suas exibições. Auxiliares de marca são aplicados como atributos a elementos HTML e são ignorados por editores que não podem processá-los. Isso permite editar e renderizar a marcação da exibição em várias ferramentas.
É possível gerar uma marcação HTML personalizada com muitos auxiliares HTML internos. Uma lógica de interface do usuário mais complexa pode ser tratada por Componentes de exibição. Componentes de exibição fornecem o mesmo SoC oferecido por controladores e exibições. Eles podem eliminar a necessidade de ações e exibições que lidam com os dados usados por elementos comuns da interface do usuário.
Como muitos outros aspectos do ASP.NET Core, as exibições dão suporte à injeção de dependência, permitindo que serviços sejam injetados em exibições.
Isolamento de CSS
Isole estilos CSS em páginas, exibições e componentes individuais para reduzir ou evitar:
- Dependências de estilos globais que podem ser desafiadoras de manter.
- Conflitos de estilo em conteúdo aninhado.
Para adicionar um arquivo CSS com escopo para uma página ou exibição, coloque os estilos CSS em um arquivo .cshtml.css
complementar correspondente ao nome do arquivo .cshtml
. No exemplo a seguir, um arquivo Index.cshtml.css
fornece estilos CSS aplicados somente à página ou exibição Index.cshtml
.
Pages/Index.cshtml.css
(Razor Pages) ou Views/Index.cshtml.css
(MVC):
h1 {
color: red;
}
O isolamento de CSS ocorre no momento do build. A estrutura reescreve seletores de CSS para fazer a correspondência da marcação renderizada pelas páginas ou exibições do aplicativo. Os estilos CSS reescritos são empacotados e produzidos como um ativo estático, {APP ASSEMBLY}.styles.css
. O espaço reservado {APP ASSEMBLY}
é o nome do assembly do projeto. Um link para os estilos CSS empacotados é colocado no layout do aplicativo.
No conteúdo <head>
do aplicativo Pages/Shared/_Layout.cshtml
(Razor Pages) ou Views/Shared/_Layout.cshtml
(MVC), adicione ou confirme a presença do link para os estilos CSS empacotados:
<link rel="stylesheet" href="~/{APP ASSEMBLY}.styles.css" />
No seguinte exemplo, o nome do assembly do aplicativo é WebApp
:
<link rel="stylesheet" href="WebApp.styles.css" />
Os estilos definidos em um arquivo CSS com escopo são aplicados apenas à saída renderizada do arquivo correspondente. No exemplo anterior, as declarações CSS h1
definidas em outro lugar no aplicativo não entram em conflito com o estilo de título de Index
. O estilo CSS em cascata e as regras de herança permanecem em vigor para arquivos CSS com escopo. Por exemplo, estilos aplicados diretamente a um elemento <h1>
no arquivo Index.cshtml
substituem os estilos do arquivo CSS com escopo em Index.cshtml.css
.
Observação
Para garantir o isolamento do estilo CSS quando o agrupamento ocorrer, não há suporte para a importação de CSS em blocos de código de Razor.
O isolamento de CSS se aplica apenas a elementos HTML. Não há suporte para isolamento de CSS para Auxiliares de Marcação.
Dentro do arquivo CSS empacotado, cada página, exibição ou componente Razor é associado a um identificador de escopo no formato b-{STRING}
, em que o espaço reservado {STRING}
é uma cadeia de caracteres de dez caracteres gerada pela estrutura. O seguinte exemplo fornece o estilo do elemento <h1>
anterior na página Index
de um aplicativo Razor Pages:
/* /Pages/Index.cshtml.rz.scp.css */
h1[b-3xxtam6d07] {
color: red;
}
Na página Index
em que o estilo CSS é aplicada do arquivo empacotado, o identificador de escopo é acrescentado como um atributo HTML:
<h1 b-3xxtam6d07>
O identificador é exclusivo para um aplicativo. No momento da compilação, um pacote de projeto é criado com a convenção {STATIC WEB ASSETS BASE PATH}/Project.lib.scp.css
, em que o espaço reservado {STATIC WEB ASSETS BASE PATH}
é o caminho base dos ativos da Web estáticos.
Se outros projetos forem utilizados, como pacotes NuGet ou bibliotecas de classes Razor, o arquivo empacotado:
- Fará referência aos estilos que usam importações de CSS.
- Não será publicado como um ativo da Web estático do aplicativo que consome os estilos.
Suporte para pré-processador de CSS
Pré-processadores de CSS são úteis para aprimorar o desenvolvimento de CSS utilizando recursos como variáveis, aninhamento, módulos, mixins e herança. Embora o isolamento de CSS não dê suporte nativo a pré-processadores CSS, como Sass ou Less, a integração de pré-processadores de CSS é contínua desde que a compilação do pré-processador ocorra antes que a estrutura reescreva os seletores de CSS durante o processo de build. Usando o Visual Studio, por exemplo, configure a compilação de pré-processador existente como uma tarefa Before Build no Gerenciador do Executor de Tarefas do Visual Studio.
Muitos pacotes NuGet de terceiros, como AspNetCore.SassCompiler
, podem compilar arquivos SASS/SCSS no início do processo de build antes que o isolamento de CSS ocorra e nenhuma configuração adicional seja necessária.
Configuração do isolamento de CSS
O isolamento de CSS permite a configuração de alguns cenários avançados, como quando há dependências em ferramentas ou fluxos de trabalho existentes.
Personalizar o formato de identificador de escopo
Nesta seção, o espaço reservado {Pages|Views}
é Pages
para aplicativos Razor Pages ou Views
para aplicativos MVC.
Por padrão, os identificadores de escopo usam o formato b-{STRING}
, em que o espaço reservado {STRING}
é uma cadeia de caracteres de dez caracteres gerada pela estrutura. Para personalizar o formato do identificador de escopo, atualize o arquivo de projeto para um padrão desejado:
<ItemGroup>
<None Update="{Pages|Views}/Index.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
No exemplo anterior, o CSS gerado para Index.cshtml.css
altera o identificador de escopo de b-{STRING}
para custom-scope-identifier
.
Use identificadores de escopo para obter a herança com arquivos CSS com escopo. No exemplo de arquivo de projeto a seguir, um arquivo BaseView.cshtml.css
contém estilos comuns entre exibições. Um arquivo DerivedView.cshtml.css
herda esses estilos.
<ItemGroup>
<None Update="{Pages|Views}/BaseView.cshtml.css" CssScope="custom-scope-identifier" />
<None Update="{Pages|Views}/DerivedView.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Use o operador curinga (*
) para compartilhar identificadores de escopo em vários arquivos:
<ItemGroup>
<None Update="{Pages|Views}/*.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Alterar o caminho base para ativos da Web estáticos
O arquivo CSS com escopo é gerado na raiz do aplicativo. No arquivo de projeto, use a propriedade StaticWebAssetBasePath
para alterar o caminho padrão. O seguinte exemplo coloca o arquivo CSS com escopo, e o rest dos ativos do aplicativo, no caminho _content
:
<PropertyGroup>
<StaticWebAssetBasePath>_content/$(PackageId)</StaticWebAssetBasePath>
</PropertyGroup>
Desabilitar o agrupamento automático
Para recusar como a estrutura publica e carrega os arquivos com escopo no runtime, use a propriedade DisableScopedCssBundling
. Ao usar essa propriedade, outras ferramentas ou processos são responsáveis por tirar os arquivos CSS isolados do diretório obj
e publicá-los e carregá-los em runtime:
<PropertyGroup>
<DisableScopedCssBundling>true</DisableScopedCssBundling>
</PropertyGroup>
Suporte à RCL (biblioteca de classes) Razor
Quando uma RCL (biblioteca de classes) Razor fornece estilos isolados, o atributo <link>
da marca href
aponta para {STATIC WEB ASSET BASE PATH}/{PACKAGE ID}.bundle.scp.css
, onde estão os espaços reservados:
{STATIC WEB ASSET BASE PATH}
: o caminho de base do ativo da Web estático.{PACKAGE ID}
: o identificador de pacote da biblioteca. O identificador de pacote usará como padrão o nome do assembly do projeto se não for especificado no arquivo de projeto.
No exemplo a seguir:
- O caminho de base do ativo da Web estático é
_content/ClassLib
. - O nome do assembly da biblioteca de classes é
ClassLib
.
Pages/Shared/_Layout.cshtml
(Razor Pages) ou Views/Shared/_Layout.cshtml
(MVC):
<link href="_content/ClassLib/ClassLib.bundle.scp.css" rel="stylesheet">
Para obter mais informações sobre RCLs, consulte os seguintes artigos:
- Interface do usuário do Razor reutilizável em bibliotecas de classes com o ASP.NET Core
- Consumir componentes do Razor de uma Razor biblioteca de classes (RCL)
Para obter informações sobre o isolamento de CSS de Blazor, consulte Isolamento de CSS do Blazor do ASP.NET Core.