Compartilhar via


Arquivos estáticos no ASP.NET Core

Note

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão do .NET 10 deste artigo.

Warning

Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão do .NET 10 deste artigo.

Arquivos estáticos, também chamados de ativos estáticos, são arquivos de um aplicativo ASP.NET Core que não são gerados dinamicamente. Em vez disso, eles são fornecidos diretamente aos clientes mediante solicitação, como arquivos HTML, CSS, imagens e JavaScript.

Para obter Blazor diretrizes de arquivos estáticos, que adiciona ou substitui as diretrizes neste artigo, consulte Arquivos estáticos do ASP.NET Core Blazor.

Para habilitar o tratamento de arquivos estáticos no ASP.NET Core, chame MapStaticAssets.

Por padrão, os arquivos estáticos são armazenados no diretório raiz da Web do projeto. O diretório padrão é {CONTENT ROOT}/wwwroot, onde o {CONTENT ROOT} espaço reservado é a raiz de conteúdo do aplicativo. Somente os arquivos na pasta wwwroot serão endereçáveis, portanto, você não precisa se preocupar com o restante do código.

Somente arquivos com extensões de arquivo específicas mapeadas para tipos de mídia com suporte são tratados como ativos da Web estáticos.

Os ativos da Web estáticos são descobertos no momento da compilação e otimizados usando fingerprinting baseado em conteúdo para impedir a reutilização de arquivos antigos. Os ativos também são compactados para reduzir o tempo de entrega de ativos.

Em runtime, os ativos da Web estáticos descobertos são expostos como pontos de extremidade com cabeçalhos HTTP aplicados, como cabeçalhos de cache e cabeçalhos de tipo de conteúdo. Um ativo é servido uma vez até que o arquivo seja alterado ou o navegador limpe seu cache. Os cabeçalhos ETag, Last-Modified e Content-Type estão definidos. O navegador é impedido de usar ativos obsoletos depois que um aplicativo é atualizado.

A entrega de ativos estáticos baseia-se no roteamento de ponto de extremidade, portanto, ele funciona com outros recursos com reconhecimento de ponto de extremidade, como autorização. Ele foi projetado para funcionar com todas as estruturas de interface do usuário, incluindo Blazor, Razor Pages e MVC.

O Mapa de Ativos Estáticos oferece os seguintes benefícios:

  • Compactação no tempo de compilação para todos os recursos no aplicativo, incluindo JavaScript (JS) e folhas de estilo, mas excluindo recursos de imagem e fonte que já estão compactados. A compactação Gzip (Content-Encoding: gz) é usada durante o desenvolvimento. A compressão Gzip e Brotli (Content-Encoding: br) é usada durante a publicação.
  • Impressão Digital para todos os ativos em tempo de compilação com uma cadeia de caracteres codificada em Base64do hash SHA-256 do conteúdo de cada arquivo. Isso impede a reutilização de uma versão antiga de um arquivo, mesmo que o arquivo antigo seja armazenado em cache. Os ativos com impressão digital são armazenados em cache usando a immutable diretiva, o que faz com que o navegador nunca mais solicite o ativo até que ele seja alterado. Para navegadores que não dão suporte à immutable diretiva, uma max-age diretiva é adicionada.
    • Mesmo que um ativo não seja fingerprintado, o conteúdo baseado em ETags é gerado para cada ativo estático usando o hash de impressão digital do arquivo como valor ETag. Isso garante que o navegador baixe apenas um arquivo se o conteúdo for alterado (ou se o arquivo estiver sendo baixado pela primeira vez).
    • Internamente, a estrutura mapeia ativos físicos para suas impressões digitais, o que permite ao aplicativo:
      • Encontre ativos gerados automaticamente, como Razor CSS com escopo de componente para o Blazorrecurso de isolamento CSS e ativos JS descritos por JS mapas de importação.
      • Gere tags de link no conteúdo <head> da página para pré-carregar recursos.

O Mapa de Ativos Estáticos não fornece recursos para minificação ou outras transformações de arquivo. A minificação geralmente é feita com código personalizado ou ferramentas de terceiros.

Para habilitar o tratamento de arquivos estáticos no ASP.NET Core, chame UseStaticFiles.

Por padrão, os arquivos estáticos são armazenados no diretório raiz da Web do projeto. O diretório padrão é {CONTENT ROOT}/wwwroot, onde o {CONTENT ROOT} espaço reservado é a raiz de conteúdo do aplicativo. Somente os arquivos na pasta wwwroot serão endereçáveis, portanto, você não precisa se preocupar com o restante do código.

Em tempo de execução, os ativos da Web estáticos são retornados pelo Middleware de Arquivo Estático quando solicitados com modificação dos ativos e com cabeçalhos de tipo de conteúdo aplicados. Os cabeçalhos ETag, Last-Modified e Content-Type estão definidos.

O Middleware de Arquivo Estático habilita o serviço de arquivos estáticos e é usado por um aplicativo quando UseStaticFiles é chamado no pipeline de processamento de solicitação do aplicativo. Os arquivos são servidos do caminho especificado em IWebHostEnvironment.WebRootPath ou WebRootFileProvider, que usa como padrão a pasta raiz da Web, normalmente wwwroot.

Você também pode servir ativos da Web estáticos de projetos e pacotes referenciados.

Alterar o diretório raiz da Web

Use o UseWebRoot método se você quiser alterar a raiz da Web. Para obter mais informações, consulte Visão geral dos conceitos básicos do ASP.NET Core.

Impedir a publicação de arquivos em wwwroot com o item de projeto <Content> no arquivo de projeto. O exemplo a seguir impede a publicação de conteúdo no wwwroot/local e em seus subdiretórios.

<ItemGroup>
  <Content Update="wwwroot\local\**\*.*" CopyToPublishDirectory="Never" />
</ItemGroup>

O método CreateBuilder define a raiz do conteúdo como o diretório atual:

var builder = WebApplication.CreateBuilder(args);

O método CreateDefaultBuilder define a raiz do conteúdo como o diretório atual:

Host.CreateDefaultBuilder(args)

No pipeline de processamento de solicitação após a chamada para UseHttpsRedirection, chame MapStaticAssets no pipeline de processamento de solicitações do aplicativo para habilitar o serviço de arquivos estáticos a partir da raiz web do aplicativo.

app.MapStaticAssets();

No pipeline de processamento de solicitação após a chamada para UseHttpsRedirection, chame UseStaticFiles no pipeline de processamento de solicitações do aplicativo para habilitar o serviço de arquivos estáticos a partir da raiz web do aplicativo.

app.UseStaticFiles();

Os arquivos estáticos são acessíveis por meio de um caminho relativo à raiz Web.

Para acessar uma imagem em wwwroot/images/favicon.png:

  • Formato de URL: https://{HOST}/images/{FILE NAME}
    • O {HOST} placeholder é o host.
    • O {FILE NAME} placeholder é o nome do arquivo.
  • Exemplos
    • URL absoluta: https://localhost:5001/images/favicon.png
    • URL relativa à raiz: images/favicon.png

Em um Blazor aplicativo, images/favicon.png carrega a imagem do ícone (favicon.png) da pasta wwwroot/images do aplicativo.

<link rel="icon" type="image/png" href="images/favicon.png" />

Em Razor páginas e aplicativos MVC, o caractere ~ til aponta para a raiz da Web. No exemplo a seguir, ~/images/favicon.png carrega a imagem do ícone (favicon.png) da pasta do wwwroot/images aplicativo:

<link rel="icon" type="image/png" href="~/images/favicon.png" />

Curto-circuito do pipeline de middleware

Para evitar a execução de todo o pipeline de middleware depois que um recurso estático for correspondido, que é o comportamento de UseStaticFiles, chame ShortCircuit em MapStaticAssets. A chamada ShortCircuit executa imediatamente o endpoint e retorna a resposta, impedindo que outros middlewares sejam executados para solicitações de recursos estáticos.

app.MapStaticAssets().ShortCircuit();

Controlar o cache de arquivos estáticos durante o desenvolvimento

Ao executar no ambiente de desenvolvimento, por exemplo, durante o teste de desenvolvimento de Recarga Dinâmica do Visual Studio, o framework substitui os cabeçalhos de cache para impedir que os navegadores armazenem arquivos estáticos em cache. Isso ajuda a garantir que a versão mais recente dos arquivos seja usada quando os arquivos forem alterados, evitando problemas com conteúdo obsoleto. Na produção, os cabeçalhos de cache corretos são definidos, permitindo que os navegadores armazenem ativos estáticos em cache conforme o esperado.

Para desabilitar esse comportamento, defina EnableStaticAssetsDevelopmentCachingtrue no arquivo de configuração do aplicativo do ambiente de desenvolvimento (appsettings.Development.json).

Arquivos estáticos em ambientes não-Development

Ao executar um aplicativo localmente, os ativos da Web estáticos só são habilitados no ambiente de Desenvolvimento. Para habilitar arquivos estáticos para ambientes diferentes do Desenvolvimento durante o desenvolvimento e teste locais (por exemplo, no ambiente de pré-produção), use UseStaticWebAssets em WebApplicationBuilder.

Warning

Ligue UseStaticWebAssets para obter o ambiente exato para impedir a ativação do recurso em produção, pois ele serve arquivos de locais separados no disco diferentes do projeto. O exemplo nesta seção verifica o ambiente de testes com IsStaging.

if (builder.Environment.IsStaging())
{
    builder.WebHost.UseStaticWebAssets();
}

Servir arquivos fora do diretório raiz da Web por meio de IWebHostEnvironment.WebRootPath

Quando IWebHostEnvironment.WebRootPath é definido como uma pasta diferente wwwroot, os seguintes comportamentos padrão são exibidos:

  • No ambiente de desenvolvimento, os ativos estáticos são servidos do wwwroot se os ativos com o mesmo nome estiverem em ambos wwwroot e em uma pasta diferente atribuída a WebRootPath.
  • Em qualquer ambiente que não seja o de desenvolvimento, recursos estáticos duplicados são atendidos da pasta WebRootPath.

Considere um aplicativo Web criado com base no modelo da Web vazio:

  • Contendo um arquivo Index.html em wwwroot e wwwroot-custom.
  • O Program arquivo é atualizado para definir WebRootPath = "wwwroot-custom".
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    WebRootPath = "wwwroot-custom"
});

Por padrão, para solicitações:/

  • No ambiente de desenvolvimento, wwwroot/Index.html é retornado.
  • Em qualquer ambiente que não seja o desenvolvimento, wwwroot-custom/Index.html é retornado.

Para garantir que os ativos de wwwroot-custom sejam sempre retornados, use uma das seguintes abordagens:

  • Excluir ativos nomeados duplicados em wwwroot.

  • Defina ASPNETCORE_ENVIRONMENT em Properties/launchSettings.json para qualquer valor diferente de Development.

  • Desative os ativos da Web estáticos definindo <StaticWebAssetsEnabled> como false no arquivo de projeto do aplicativo. AVISO: Desabilitar ativos da Web estáticos desabilita Razor bibliotecas de classes.

  • Adicione o seguinte XML ao arquivo de projeto:

    <ItemGroup>
      <Content Remove="wwwroot\**" />
    </ItemGroup>
    

O código a seguir atualiza WebRootPath para um valor não relacionado ao Desenvolvimento (Staging), assegurando que o conteúdo duplicado seja obtido do wwwroot-custom em vez de wwwroot.

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    EnvironmentName = Environments.Staging,
    WebRootPath = "wwwroot-custom"
});

Middleware de arquivos estáticos

O Middleware de Arquivo Estático permite o serviço de arquivo estático em cenários de arquivos estáticos específicos, geralmente além das convenções de roteamento de ponto de extremidade de Ativos Estáticos do Mapa (MapStaticAssets).

O Middleware de Arquivo Estático é incluído no processamento de solicitações quando UseStaticFiles é chamado no pipeline de processamento de solicitação do aplicativo, normalmente depois que as convenções de ponto de extremidade de Ativos Estáticos do Mapa (MapStaticAssets) são adicionadas.

As convenções de endpoint do Map Static Assets são usadas em aplicativos direcionados ao .NET 9 ou posterior. O Middleware de Arquivo Estático deve ser usado em aplicativos destinados a versões do .NET antes do .NET 9.

O Middleware de Arquivo Estático serve arquivos estáticos, mas não fornece o mesmo nível de otimização das convenções de endpoint do Map Static Assets. Os recursos de compactação de tempo de build e impressão digital das convenções de ponto de extremidade de Ativos Estáticos do Mapa não estão disponíveis quando se baseia apenas no Middleware de Arquivo Estático.

As convenções de ponto de extremidade são otimizadas para servir ativos dos quais o aplicativo tem conhecimento em tempo de execução. Se o aplicativo servir ativos de outros locais, como disco ou recursos incorporados, o Static File Middleware deverá ser usado.

Os seguintes recursos abordados neste artigo têm suporte com o Middleware para Arquivos Estáticos, mas não com os pontos de extremidade das convenções para Mapear Ativos Estáticos.

Servir arquivos fora do diretório raiz da Web por meio de UseStaticFiles

Considere a seguinte hierarquia de diretório com arquivos estáticos que residem fora da raiz da Web do aplicativo em uma pasta chamada ExtraStaticFiles:

  • wwwroot
    • css
    • images
    • js
  • ExtraStaticFiles
    • images
      • red-rose.jpg

Uma solicitação pode acessar red-rose.jpg configurando uma nova instância do Middleware de Arquivo Estático:

Namespaces para a API a seguir:

using Microsoft.Extensions.FileProviders;

No pipeline de processamento de solicitações, logo após a chamada já existente para MapStaticAssets (.NET 9 ou posterior) ou UseStaticFiles (.NET 8 ou anterior):

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles")),
    RequestPath = "/static-files"
});

No código anterior, a hierarquia de ExtraStaticFiles diretório é exposta publicamente por meio do static-files segmento de URL. Uma solicitação para https://{HOST}/StaticFiles/images/red-rose.jpg, onde o espaço reservado {HOST} é o host, serve o arquivo red-rose.jpg.

As seguintes referências de marcação ExtraStaticFiles/images/red-rose.jpg:

<img src="static-files/images/red-rose.jpg" alt="A red rose" />

Para o exemplo anterior, há suporte para a notação de barra de blocos em Razor páginas e exibições MVC (src="~/StaticFiles/images/red-rose.jpg"), não para Razor componentes em Blazor aplicativos.

Fornecer arquivos de vários locais

As orientações nesta seção se aplicam a aplicativos Pages e MVC. Para obter diretrizes que se aplicam aos Blazor Web Apps, consulte Arquivos estáticos do ASP.NET Core Blazor.

Considere a seguinte marcação que exibe um logotipo da empresa:

<img src="~/logo.png" asp-append-version="true" alt="Company logo">

O desenvolvedor pretende usar o Image Tag Helper para acrescentar uma versão e servir o arquivo a partir de um local personalizado, uma pasta chamada ExtraStaticFiles.

O exemplo a seguir chama MapStaticAssets para fornecer arquivos de wwwroot e UseStaticFiles para fornecer arquivos de ExtraStaticFiles:

No pipeline de processamento de solicitações, logo após a chamada já existente para MapStaticAssets (.NET 9 ou posterior) ou UseStaticFiles (.NET 8 ou anterior):

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"))
});

O exemplo a seguir chama UseStaticFiles duas vezes para atender arquivos de ambos wwwroot e ExtraStaticFiles.

No pipeline de processamento de solicitação, após a chamada existente para UseStaticFiles:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"))
});

Usando o código anterior, o ExtraStaticFiles/logo.png arquivo é exibido. No entanto, o Image Tag Helper (AppendVersion) não é aplicado porque este depende de WebRootFileProvider, o qual não foi atualizado para incluir o diretório ExtraStaticFiles.

O código a seguir atualiza o WebRootFileProvider para incluir a pasta ExtraStaticFiles usando um CompositeFileProvider. Isso permite que o Auxiliar de Marca de Imagem aplique uma versão às imagens na ExtraStaticFiles pasta.

Namespace para a seguinte API:

using Microsoft.Extensions.FileProviders;

No pipeline de processamento de solicitação antes da chamada existente para MapStaticAssets (.NET 9 ou posterior) ou UseStaticFiles (.NET 8 ou anterior):

var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
    Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"));

var compositeProvider = new CompositeFileProvider(webRootProvider, newPathProvider);

app.Environment.WebRootFileProvider = compositeProvider;

UseStaticFiles e UseFileServer padrão para o provedor de arquivos apontando para wwwroot. Instâncias adicionais de UseStaticFiles e UseFileServer podem ser fornecidas com outros provedores de arquivos para fornecer arquivos de outros locais. Para obter mais informações, consulte UseStaticFiles ainda necessário com UseFileServer para wwwroot (dotnet/AspNetCore.Docs nº 15578).

Definir cabeçalhos de resposta HTTP

Use StaticFileOptions para definir cabeçalhos de resposta HTTP. Além de configurar o Middleware de Arquivo Estático para fornecer arquivos estáticos, o código a seguir define o Cache-Control cabeçalho como 604.800 segundos (uma semana).

Namespaces para a API a seguir:

using Microsoft.AspNetCore.Http;

No pipeline de processamento de solicitações, logo após a chamada já existente para MapStaticAssets (.NET 9 ou posterior) ou UseStaticFiles (.NET 8 ou anterior):

app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        ctx.Context.Response.Headers.Append(
            "Cache-Control", "public, max-age=604800");
    }
});

Grande coleção de ativos

Ao lidar com grandes coleções de ativos, que são considerados cerca de 1.000 ou mais ativos, recomendamos usar um empacotador para reduzir o número final de ativos atendidos pelo aplicativo ou combinar MapStaticAssets com UseStaticFiles.

MapStaticAssets carrega ansiosamente os metadados pré-compilados capturados durante o processo de build para os recursos, a fim de dar suporte à compactação, ao cache e à impressão digital. Esses recursos vêm ao custo de maior uso de memória pelo aplicativo. Para ativos que são acessados com frequência, geralmente vale os custos. Para ativos que não são acessados com frequência, a compensação pode não valer os custos.

Se você não usar o agrupamento, recomendamos que você combine MapStaticAssets com UseStaticFiles. O exemplo a seguir demonstra a abordagem.

No arquivo de projeto (.csproj), a propriedade MSBuild StaticWebAssetEndpointExclusionPattern é usada para filtrar endpoints do manifesto final para MapStaticAssets. Os arquivos excluídos são servidos por UseStaticFiles e não se beneficiam de compactação, cache e identificação por impressão digital.

Ao definir o valor de StaticWebAssetEndpointExclusionPattern, mantenha $(StaticWebAssetEndpointExclusionPattern) para manter o padrão de exclusão padrão da estrutura. Adicione padrões adicionais em uma lista separada por ponto-e-vírgula.

No exemplo a seguir, o padrão de exclusão adiciona os arquivos estáticos na pasta lib/icons, que representa um lote hipotético de ícones.

<StaticWebAssetEndpointExclusionPattern>
  $(StaticWebAssetEndpointExclusionPattern);lib/icons/**
</StaticWebAssetEndpointExclusionPattern>

Após o processamento do Middleware de Redirecionamento HTTPS (app.UseHttpsRedirection();) no arquivo Program.

app.UseStaticFiles();

app.UseAuthorization();

app.MapStaticAssets();

Autorização de arquivo estático

Quando um aplicativo adota uma política de autorização de fallback, a autorização é necessária para todas as solicitações que não especificam explicitamente uma política de autorização, incluindo solicitações de arquivos estáticos após o processamento das solicitações pelo Middleware de Autorização. Permitir acesso anônimo a arquivos estáticos aplicando-se AllowAnonymousAttribute ao configurador de endpoints para arquivos estáticos.

app.MapStaticAssets().Add(endpointBuilder => 
    endpointBuilder.Metadata.Add(new AllowAnonymousAttribute()));

Quando um aplicativo adota uma política de autorização de fallback, a autorização é necessária para todas as solicitações que não especificam explicitamente uma política de autorização, incluindo solicitações de arquivos estáticos após o processamento das solicitações pelo Middleware de Autorização. Os modelos do ASP.NET Core permitem acesso anônimo a arquivos estáticos chamando UseStaticFiles antes de chamar UseAuthorization. A maioria dos aplicativos segue esse padrão. Quando o Middleware de arquivo estático é chamado antes do middleware de autorização:

  • Nenhuma verificação de autorização é executada nos arquivos estáticos.
  • Os arquivos estáticos servidos pelo Middleware de Arquivos Estáticos, como a raiz da Web (normalmente, wwwroot), são publicamente acessíveis.

Para fornecer arquivos estáticos com base na autorização:

Namespaces para a API a seguir:

using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.FileProviders;

Registro de serviço:

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
});

No pipeline de processamento de solicitação após a chamada para UseAuthorization:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "SecureStaticFiles")),
    RequestPath = "/static-files"
});

Namespaces para a API a seguir:

using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.FileProviders;

Em Startup.ConfigureServices:

services.AddAuthorization(options =>
{
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
});

Após a chamada para Startup.Configure, em UseAuthorization

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.ContentRootPath, "SecureStaticFiles")),
    RequestPath = "/static-files"
});

No código anterior, a política de autorização de fallback requer usuários autenticados. Endpoints, como controladores e Razor Páginas, que especificam seus próprios requisitos de autorização não usam a política de autorização padrão. Por exemplo, Páginas do Razor, controladores ou métodos de ação com [AllowAnonymous] ou [Authorize(PolicyName="MyPolicy")] usam o atributo de autorização aplicado em vez da política de autorização de fallback.

RequireAuthenticatedUser adiciona DenyAnonymousAuthorizationRequirement à instância atual, que impõe que o usuário atual seja autenticado.

Os ativos estáticos armazenados na raiz da web do aplicativo são publicamente acessíveis porque o middleware de arquivo estático padrão (UseStaticFiles) é chamado antes do UseAuthorization. Os ativos estáticos na SecureStaticFiles pasta exigem autenticação.

Uma abordagem alternativa para fornecer arquivos com base na autorização é:

  • Armazene os arquivos fora da raiz do servidor web ou de qualquer diretório acessível ao Middleware para Arquivos Estáticos.
  • Sirva os arquivos por meio de um método de ação ao qual a autorização é aplicada e retorne um FileResult objeto.

De uma Razor página (Pages/BannerImage.cshtml.cs):

public class BannerImageModel : PageModel
{
    private readonly IWebHostEnvironment _env;

    public BannerImageModel(IWebHostEnvironment env) => _env = env;

    public PhysicalFileResult OnGet()
    {
        var filePath = Path.Combine(
            _env.ContentRootPath, "SecureStaticFiles", "images", "red-rose.jpg");

        return PhysicalFile(filePath, "image/jpeg");
    }
}

De um controlador (Controllers/HomeController.cs):

[Authorize]
public IActionResult BannerImage()
{
    var filePath = Path.Combine(
        _env.ContentRootPath, "SecureStaticFiles", "images", "red-rose.jpg");

    return PhysicalFile(filePath, "image/jpeg");
}

A abordagem anterior exige uma página ou um ponto de extremidade por arquivo.

O exemplo de endpoint de rota a seguir retorna arquivos para usuários autenticados.

No arquivo Program:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AuthenticatedUsers", b => b.RequireAuthenticatedUser());
});

...

app.MapGet("/files/{fileName}", IResult (string fileName) => 
{
    var filePath = GetOrCreateFilePath(fileName);

    if (File.Exists(filePath))
    {
        return TypedResults.PhysicalFile(filePath, fileName);
    }

    return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");

O exemplo de endpoint de rota a seguir faz upload de arquivos para usuários que estão autenticados na função de administrador ("admin").

No arquivo Program:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdminsOnly", b => b.RequireRole("admin"));
});

...

// IFormFile uses memory buffer for uploading. For handling large 
// files, use streaming instead. See the *File uploads* article
// in the ASP.NET Core documentation:
// https://learn.microsoft.com/aspnet/core/mvc/models/file-uploads
app.MapPost("/files", async (IFormFile file, LinkGenerator linker, 
    HttpContext context) =>
{
    // Don't rely on the value in 'file.FileName', as it's only metadata that can 
    // be manipulated by the end-user. Consider the 'Utilities.IsFileValid' method 
    // that takes an 'IFormFile' and validates its signature within the 
    // 'AllowedFileSignatures'.

    var fileSaveName = Guid.NewGuid().ToString("N") + 
        Path.GetExtension(file.FileName);
    await SaveFileWithCustomFileName(file, fileSaveName);

    context.Response.Headers.Append("Location", linker.GetPathByName(context, 
        "GetFileByName", new { fileName = fileSaveName}));

    return TypedResults.Ok("File Uploaded Successfully!");
})
.RequireAuthorization("AdminsOnly");

Em Startup.ConfigureServices:

services.AddAuthorization(options =>
{
    options.AddPolicy("AuthenticatedUsers", b => b.RequireAuthenticatedUser());
});

Em Startup.Configure:

app.MapGet("/files/{fileName}", IResult (string fileName) => 
{
    var filePath = GetOrCreateFilePath(fileName);

    if (File.Exists(filePath))
    {
        return TypedResults.PhysicalFile(filePath, fileName);
    }

    return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");

O código a seguir carrega arquivos para usuários autenticados na função de administrador ("admin").

Em Startup.ConfigureServices:

services.AddAuthorization(options =>
{
    options.AddPolicy("AdminsOnly", b => b.RequireRole("admin"));
});

Em Startup.Configure:

// IFormFile uses memory buffer for uploading. For handling large 
// files, use streaming instead. See the *File uploads* article
// in the ASP.NET Core documentation:
// https://learn.microsoft.com/aspnet/core/mvc/models/file-uploads
app.MapPost("/files", async (IFormFile file, LinkGenerator linker, 
    HttpContext context) =>
{
    // Don't rely on the value in 'file.FileName', as it's only metadata that can 
    // be manipulated by the end-user. Consider the 'Utilities.IsFileValid' method 
    // that takes an 'IFormFile' and validates its signature within the 
    // 'AllowedFileSignatures'.

    var fileSaveName = Guid.NewGuid().ToString("N") + 
        Path.GetExtension(file.FileName);
    await SaveFileWithCustomFileName(file, fileSaveName);

    context.Response.Headers.Append("Location", linker.GetPathByName(context, 
        "GetFileByName", new { fileName = fileSaveName}));

    return TypedResults.Ok("File Uploaded Successfully!");
})
.RequireAuthorization("AdminsOnly");

Navegação de diretório

A navegação no diretório permite a listagem de diretórios nos diretórios especificados.

A navegação no diretório está desabilitada por padrão por motivos de segurança. Para obter mais informações, consulte Considerações sobre segurança relacionadas a arquivos estáticos.

Habilite a navegação de diretório com a seguinte API:

No exemplo a seguir:

  • Uma images pasta na raiz do aplicativo contém imagens para navegação de diretório.
  • O caminho da solicitação para procurar as imagens é /DirectoryImages.
  • Chamar UseStaticFiles e definir FileProvider habilita a exibição de links do navegador de StaticFileOptions para os arquivos individuais.

Namespaces para a API a seguir:

using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;

Registro de serviço:

builder.Services.AddDirectoryBrowser();

No pipeline de processamento de solicitações, logo após a chamada já existente para MapStaticAssets (.NET 9 ou posterior) ou UseStaticFiles (.NET 8 ou anterior):

var fileProvider = new PhysicalFileProvider(
    Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/DirectoryImages";

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = fileProvider,
    RequestPath = requestPath
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = fileProvider,
    RequestPath = requestPath
});

Namespaces para a API a seguir:

using Microsoft.Extensions.FileProviders;
using System.IO;

Em Startup.ConfigureServices:

services.AddDirectoryBrowser();

Em Startup.Configure, na sequência da chamada existente para UseStaticFiles.

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/DirectoryImages"
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/DirectoryImages"
});

O código anterior permite a navegação em diretórios da pasta wwwroot/images usando o URL https://{HOST}/DirectoryImages com links para cada arquivo e pasta, em que o espaço reservado {HOST} é o host.

AddDirectoryBrowser adiciona serviços exigidos pelo Middleware de Navegação do Diretório, incluindo HtmlEncoder. Esses serviços podem ser adicionados por outras chamadas, como AddRazorPages, mas recomendamos chamar AddDirectoryBrowser para garantir que os serviços sejam adicionados.

Fornecer documentos padrão

Definir uma página padrão fornece aos visitantes um ponto de partida em um site. Para servir um arquivo padrão a partir de wwwroot sem exigir que a URL de solicitação inclua o nome do arquivo, chame o método UseDefaultFiles.

UseDefaultFiles é um reescritor de URL que não serve o arquivo. No pipeline de processamento de solicitação antes da chamada existente para MapStaticAssets (.NET 9 ou posterior) ou UseStaticFiles (.NET 8 ou anterior):

app.UseDefaultFiles();

Com UseDefaultFiles, as solicitações para uma pasta em wwwroot visam procurar:

  • default.htm
  • default.html
  • index.htm
  • index.html

O primeiro arquivo encontrado na lista é fornecido como se a solicitação fosse incluída no nome do arquivo. A URL do navegador continua refletindo o URI solicitado.

O seguinte código altera o nome do arquivo padrão para default-document.html:

var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("default-document.html");
app.UseDefaultFiles(options);

Combinar arquivos estáticos, documentos padrão e navegação de diretório

UseFileServer combina a funcionalidade de UseStaticFiles, UseDefaultFiles e opcionalmente UseDirectoryBrowser.

No pipeline de processamento de solicitações, após a chamada existente para MapStaticAssets (.NET 9 ou posterior) ou UseStaticFiles (.NET 8 ou anterior), chame UseFileServer para permitir a disponibilização de arquivos estáticos e do arquivo padrão.

app.UseFileServer();

A navegação de diretório não está habilitada para o exemplo anterior.

O código a seguir habilita o fornecimento de arquivos estáticos, o arquivo padrão e a navegação de diretório.

Registro de serviço:

builder.Services.AddDirectoryBrowser();

No pipeline de processamento de solicitação, após a chamada existente para UseStaticFiles:

app.UseFileServer(enableDirectoryBrowsing: true);

Em Startup.ConfigureServices:

services.AddDirectoryBrowser();

Em Startup.Configure, na sequência da chamada existente para UseStaticFiles.

app.UseFileServer(enableDirectoryBrowsing: true);

Para o endereço do host (/), UseFileServer retorna o documento HTML padrão antes da página padrão Razor (Pages/Index.cshtml) ou do modo de exibição MVC padrão (Home/Index.cshtml).

Considere a seguinte hierarquia de diretórios:

  • wwwroot
    • css
    • images
    • js
  • ExtraStaticFiles
    • images
      • logo.png
    • default.html

O código a seguir habilita o fornecimento de arquivos estáticos, o arquivo padrão e a navegação de diretório de ExtraStaticFiles.

Namespaces para a API a seguir:

using Microsoft.Extensions.FileProviders;

Registro de serviço:

builder.Services.AddDirectoryBrowser();

No pipeline de processamento de solicitação, após a chamada existente para UseStaticFiles:

app.UseFileServer(new FileServerOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles")),
    RequestPath = "/static-files",
    EnableDirectoryBrowsing = true
});

Namespaces para a API a seguir:

using Microsoft.Extensions.FileProviders;
using System.IO;

Em Startup.ConfigureServices:

services.AddDirectoryBrowser();

Em Startup.Configure, na sequência da chamada existente para UseStaticFiles.

app.UseFileServer(new FileServerOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.ContentRootPath, "ExtraStaticFiles")),
    RequestPath = "/static-files",
    EnableDirectoryBrowsing = true
});

AddDirectoryBrowser precisa ser chamado quando o valor da propriedade EnableDirectoryBrowsing é true.

Usando o código e a hierarquia de arquivos anteriores, as URLs são resolvidas como mostrado na tabela a seguir (o espaço reservado {HOST} é o host).

URI Arquivo de resposta
https://{HOST}/static-files/images/logo.png ExtraStaticFiles/images/logo.png
https://{HOST}/static-files ExtraStaticFiles/default.html

Se nenhum arquivo com o nome padrão existir no diretório ExtraStaticFiles, https://{HOST}/static-files retornará a listagem do diretório com links clicáveis, em que o marcador {HOST} é o host.

UseDefaultFiles e UseDirectoryBrowser executam um redirecionamento do lado do cliente do URI de destino sem um / à direita para o URI de destino com um / à direita. Por exemplo, de https://{HOST}/static-files (sem sequência final /) para https://{HOST}/static-files/ (inclui uma sequência final /). As URLs relativas no diretório ExtraStaticFiles são inválidas sem uma barra final (/), a menos que a opção RedirectToAppendTrailingSlash de DefaultFilesOptions seja usada.

Mapear extensões de arquivo para tipos MIME

Note

Para obter diretrizes que se aplicam a Blazor aplicativos, consulte ASP.NET Arquivos estáticos principaisBlazor.

Use FileExtensionContentTypeProvider.Mappings para adicionar ou modificar a extensão de arquivo para mapeamentos de tipo de conteúdo MIME. No exemplo a seguir, várias extensões de arquivo são mapeadas para tipos MIME conhecidos. A .rtf extensão é substituída e .mp4 removida:

using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;

...

// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos
provider.Mappings.Remove(".mp4");

app.UseStaticFiles(new StaticFileOptions
{
    ContentTypeProvider = provider
});

Quando você tiver várias opções de arquivo estático para configurar, você poderá, como alternativa, definir o provedor usando StaticFileOptions:

var provider = new FileExtensionContentTypeProvider();

...

builder.Services.Configure<StaticFileOptions>(options =>
{
    options.ContentTypeProvider = provider;
});

app.UseStaticFiles();

Em Startup.Configure:

using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
using System.IO;

...

// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos
provider.Mappings.Remove(".mp4");

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/images",
    ContentTypeProvider = provider
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/images"
});

Para obter mais informações, consulte tipos de conteúdo MIME.

Tipos de conteúdo não padrão

O middleware de arquivo estático compreende quase 400 tipos de conteúdo de arquivo conhecidos. Se o usuário solicitar um arquivo com um tipo de arquivo desconhecido, o middleware de arquivo estático aprovará a solicitação para o próximo middleware no pipeline. Se nenhum middleware manipular a solicitação, uma resposta 404 Não Encontrado será retornada. Se a navegação no diretório estiver habilitada, um link para o arquivo será exibido na lista do diretório.

O código a seguir permite servir tipos de conteúdo desconhecidos e renderiza o arquivo desconhecido como uma imagem:

app.UseStaticFiles(new StaticFileOptions
{
    ServeUnknownFileTypes = true,
    DefaultContentType = "image/png"
});

Com o código anterior, uma solicitação para um arquivo com um tipo de conteúdo desconhecido é retornada como uma imagem.

Warning

Habilitar ServeUnknownFileTypes é um risco à segurança. Ela está desabilitada por padrão, e seu uso não é recomendado. As extensões de arquivo de mapa para tipos MIME fornecem uma alternativa mais segura para atender arquivos com extensões não padrão.

Fornecer um manifesto de arquivos estáticos personalizados

Se staticAssetsManifestPath for null, o IHostEnvironment.ApplicationName é usado para localizar o manifesto. Como alternativa, especifique um caminho completo para o arquivo de manifesto. Se um caminho relativo for usado, a estrutura procurará o arquivo no AppContext.BaseDirectory.

Considerações de segurança para arquivos estáticos

Warning

UseDirectoryBrowser e UseStaticFiles podem vazar segredos. A desabilitação da navegação no diretório em produção é altamente recomendada. Examine com atenção os diretórios que são habilitados por meio de UseStaticFiles ou UseDirectoryBrowser. Todo o diretório e seus subdiretórios se tornam publicamente acessíveis. Armazene arquivos adequados para fornecimento ao público em um diretório dedicado, como <content_root>/wwwroot. Separe esses arquivos das exibições MVC, Razor Páginas, arquivos de configuração, etc.

  • As URLs para o conteúdo exposto com UseDirectoryBrowser e UseStaticFiles estão sujeitas à diferenciação de maiúsculas e minúsculas e a restrições de caracteres do sistema de arquivos subjacente. Por exemplo, o Windows diferencia maiúsculas de minúsculas, mas o macOS e o Linux não.

  • Os aplicativos ASP.NET Core hospedados no IIS usam o Módulo do ASP.NET Core para encaminhar todas as solicitações ao aplicativo, inclusive as solicitações de arquivo estático. O manipulador de arquivo estático de IIS não é usado e não tem nenhuma chance de lidar com solicitações.

  • Conclua as etapas seguinte no Gerenciador do IIS para remover o manipulador de arquivos estáticos no IIS no nível do servidor ou do site:

    1. Navegue para o recurso Módulos.
    2. Selecione StaticFileModule na lista.
    3. Clique em Remover na barra lateral Ações.

Warning

Se o manipulador de arquivo estático do IIS estiver habilitado e o Módulo do ASP.NET Core não estiver configurado corretamente, os arquivos estáticos serão atendidos. Isso acontece, por exemplo, se o web.config arquivo não for implantado.

  • Coloque arquivos de código, incluindo .cs e .cshtml, fora da raiz Web do projeto de aplicativo. Portanto, uma separação lógica é criada entre o conteúdo do lado do cliente do aplicativo e o código baseado em servidor. Isso impede a perda de código do lado do servidor.

Propriedades do MSBuild

As tabelas a seguir mostram as propriedades e descrições de metadados do MSBuild dos arquivos estáticos.

Propriedade Description
EnableDefaultCompressedItems Habilita padrões padrão de inclusão/exclusão de compactação.
CompressionIncludePatterns Lista separada por ponto-e-vírgula de padrões de arquivo a serem incluídos para compactação.
CompressionExcludePatterns Lista separada por ponto-e-vírgula de padrões de arquivo a serem excluídos da compactação.
EnableDefaultCompressionFormats Habilita formatos de compactação padrão (Gzip e Brotli).
BuildCompressionFormats Formatos de compactação a serem usados durante o build.
PublishCompressionFormats Formatos de compactação a serem usados durante a publicação.
DisableBuildCompression Desabilita a compactação durante a compilação.
CompressDiscoveredAssetsDuringBuild Compacta ativos descobertos durante a compilação.
BrotliCompressionLevel Nível de compactação para o algoritmo Brotli.
StaticWebAssetBuildCompressAllAssets Compacta todos os ativos durante o build, não apenas ativos descobertos ou computados durante um build.
StaticWebAssetPublishCompressAllAssets Compacta todos os ativos durante a publicação, não apenas ativos descobertos ou computados durante um build.
Propriedade Description
StaticWebAssetBasePath Caminho de URL base para todos os recursos em uma biblioteca.
StaticWebAssetsFingerprintContent Habilita a impressão digital de conteúdo para a quebra de cache.
StaticWebAssetFingerprintingEnabled Habilita o recurso de impressão digital para ativos da Web estáticos.
StaticWebAssetsCacheDefineStaticWebAssetsEnabled Habilita o cache para configurações de recursos da web estáticos.
StaticWebAssetEndpointExclusionPattern Padrão para excluir pontos de extremidade.
Grupo de itens Description Metadados
StaticWebAssetContentTypeMapping Mapeia padrões de arquivo para tipos de conteúdo e cabeçalhos de cache para pontos de extremidade. Pattern, Cache
StaticWebAssetFingerprintPattern Define padrões para aplicar impressões digitais a ativos da Web estáticos para a quebra de cache. Pattern, Expression

Descrições de metadados:

  • Pattern: um padrão glob usado para corresponder a arquivos. Para StaticWebAssetContentTypeMapping, ele corresponde a arquivos para determinar seu tipo de conteúdo (por exemplo, *.js para arquivos JavaScript). Para StaticWebAssetFingerprintPattern, ele identifica arquivos de várias extensões que exigem tratamento especial de impressão digital (por exemplo, *.lib.module.js).

  • Cache: especifica o valor do Cache-Control cabeçalho para o tipo de conteúdo correspondente. Isso controla o comportamento de cache do navegador (por exemplo, max-age=3600, must-revalidate para arquivos de mídia).

  • Expression: define como a impressão digital é inserida no nome do arquivo. O padrão é #[.{FINGERPRINT}], que insere a impressão digital ({FINGERPRINT} espaço reservado) antes da extensão.

O exemplo a seguir mapeia o padrão de arquivo bitmap (.bmp) para o tipo de conteúdo image/bmp com o espaço reservado {CACHE HEADER} representando o cabeçalho Cache-Control a ser usado em endpoints sem identificação digital:

<ItemGroup>
  <StaticWebAssetContentTypeMapping Include="image/bmp" Cache="{CACHE HEADER}" Pattern="*.bmp" />
</ItemGroup>

Opções de configuração de runtime

A tabela a seguir descreve as opções de configuração de runtime.

Chave de configuração Description
ReloadStaticAssetsAtRuntime Habilita a atualização de ativos estáticos durante o tempo de desenvolvimento: fornece arquivos modificados da raiz do site (wwwroot) (recalcula ETag, recompacta se necessário) em vez das versões do manifesto de tempo de compilação. O padrão é que esteja habilitado somente ao servir um manifesto de build, a menos que seja definido explicitamente.
DisableStaticAssetNotFoundRuntimeFallback Quando true, suprime o ponto de extremidade de fallback que atende arquivos recém-adicionados não presentes no manifesto de build. Quando false está ausente, um fallback de verificação de existência do arquivo {**path} (GET/HEAD) registra um aviso e serve o arquivo com um valor computado ETag.
EnableStaticAssetsDevelopmentCaching Quando true, preserva os cabeçalhos originais Cache-Control em descritores de ativos. Quando false ou ausente, reescreve os cabeçalhos Cache-Control para no-cache a fim de evitar o cache agressivo do cliente durante o desenvolvimento.
EnableStaticAssetsDevelopmentIntegrity Quando true, mantém propriedades de integridade em descritores de ativos. Quando false ou ausente, remove qualquer propriedade de integridade para evitar incompatibilidades quando os arquivos são alterados durante o desenvolvimento.

Recursos adicionais