Arquivos estáticos no ASP.NET Core
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Aviso
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 .NET 9 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para a versão atual, consulte a versão .NET 9 deste artigo.
Por Rick Anderson
Arquivos estáticos, como HTML, CSS, imagens e JavaScript, são ativos que um aplicativo ASP.NET Core fornece diretamente para os clientes por padrão.
Para obter diretrizes sobre arquivos estáticos Blazor, que adicionam ou se sobrepõem às diretrizes deste artigo, consulte Arquivos estáticos do ASP.NET Core Blazor.
Fornecer arquivos estáticos
Os arquivos estáticos são armazenados no diretório raiz Web do projeto. O diretório padrão é {content root}/wwwroot
, mas pode ser alterado com o método UseWebRoot. Para obter mais informações, consulte Raiz de conteúdo e Raiz web.
O método CreateBuilder define a raiz do conteúdo como o diretório atual:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Os arquivos estáticos são acessíveis por meio de um caminho relativo à raiz Web. Por exemplo, os modelos de projeto do Aplicativo Web contêm várias pastas dentro da pasta wwwroot
:
wwwroot
css
js
lib
Considere um aplicativo com o arquivo wwwroot/images/MyImage.jpg
. O formato de URI para acessar um arquivo na pasta images
é https://<hostname>/images/<image_file_name>
. Por exemplo, https://localhost:5001/images/MyImage.jpg
MapStaticAssets
A criação de aplicativos Web com bom desempenho requer a otimização do fornecimento de ativos ao navegador. As possíveis otimizações incluem:
- Forneça um determinado ativo uma vez até que o arquivo seja alterado ou o navegador limpe seu cache. Definir o cabeçalho da ETag.
- Impedir que o navegador use ativos antigos ou obsoletos depois que um aplicativo for atualizado. Definir o cabeçalho Last-Modified.
- Configurar os cabeçalhos de cache adequadamente.
- Use o middleware de cache.
- Fornecer versões comprimidas dos ativos quando possível.
- Use um CDN para fornecer os ativos mais próximos do usuário.
- Minimize o tamanho dos ativos fornecidos ao navegador. Essa otimização não inclui a minificação.
MapStaticAssets são convenções de endpoint de roteamento que otimizam a entrega de ativos estáticos em um aplicativo. Ele foi projetado para funcionar com todas as estruturas de interface do usuário, incluindo Blazor, Razor Pages e MVC.
UseStaticFiles
também exibe arquivos estáticos, mas não fornece o mesmo nível de otimização que MapStaticAssets
. Para obter uma comparação de UseStaticFiles
e MapStaticAssets
, veja Otimização da entrega de ativos da Web estáticos .
Fornecer arquivos na raiz Web
Os modelos de aplicativo Web padrão chamam o método MapStaticAssets no Program.cs
, que permite que arquivos estáticos sejam fornecidos:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
A sobrecarga do método UseStaticFiles
sem parâmetro marca os arquivos raiz Web como fornecíveis. As seguintes referências de marcação wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Na marcação anterior, o caractere ~
de til aponta para a raiz Web.
Fornecer arquivos fora do diretório base
Considere uma hierarquia de diretórios na qual os arquivos estáticos a serem fornecidos residam fora da raiz Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Uma solicitação pode acessar o arquivo red-rose.jpg
configurando o middleware de arquivo estático da seguinte maneira:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(); //Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
No código anterior, a hierarquia de diretórios MyStaticFiles é exposta publicamente por meio do segmento do URI StaticFiles. Uma solicitação para https://<hostname>/StaticFiles/images/red-rose.jpg
fornece ao arquivo red-rose.jpg
.
As seguintes referências de marcação MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Para fornecer arquivos de vários locais, consulte Fornecer arquivos de vários locais.
Definir cabeçalhos de resposta HTTP
Um objeto StaticFileOptions pode ser usado para definir cabeçalhos de resposta HTTP. Além de configurar o fornecimento de arquivo estático da raiz Web, o seguinte código define o cabeçalho de controle por cache:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
O código anterior disponibiliza arquivos estáticos publicamente no cache local por uma semana.
Autorização de arquivo estático
Os modelos de ASP.NET Core chamam MapStaticAssets 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 fornecidos pelo Middleware de arquivo estático, como aqueles em
wwwroot
, são acessíveis publicamente.
Para fornecer arquivos estáticos com base na autorização:
- Armazene-os fora de
wwwroot
. - Chame
UseStaticFiles
, especificando um caminho, depois de chamarUseAuthorization
. - Defina a política de autorização de fallback.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using StaticFileAuth.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.MapRazorPages();
app.Run();
No código anterior, a política de autorização de fallback exige que todos os usuários sejam autenticados. Pontos de extremidade, como controladores, Páginas do Razor etc., que especificam seus próprios requisitos de autorização não usam a política de autorização de fallback. 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 em wwwroot
são acessíveis publicamente porque o middleware de arquivo estático padrão (app.UseStaticFiles();
) é chamado antes de UseAuthentication
. Os ativos estáticos na pasta MyStaticFiles exigem autenticação. O código de amostra demonstra isso.
Uma abordagem alternativa para fornecer arquivos com base na autorização é:
Armazene-os fora do
wwwroot
e de qualquer diretório acessível ao middleware de arquivo estático.Forneça-os por meio de um método de ação ao qual a autorização é aplicada e retorne um objeto FileResult:
[Authorize] public class BannerImageModel : PageModel { private readonly IWebHostEnvironment _env; public BannerImageModel(IWebHostEnvironment env) => _env = env; public PhysicalFileResult OnGet() { var filePath = Path.Combine( _env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg"); return PhysicalFile(filePath, "image/jpeg"); } }
A abordagem anterior exige uma página ou um ponto de extremidade por arquivo. O seguinte código retorna ou carrega arquivos para os usuários autenticados:
app.MapGet("/files/{fileName}", IResult (string fileName) =>
{
var filePath = GetOrCreateFilePath(fileName);
if (File.Exists(filePath))
{
return TypedResults.PhysicalFile(filePath, fileDownloadName: $"{fileName}");
}
return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");
app.MapPost("/files",
async (IFormFile file, LinkGenerator linker, HttpContext context) =>
{
// Don't rely on the file.FileName as it is only metadata that can be
// manipulated by the end-user. See 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");
app.Run();
IFormFile no exemplo anterior usa o buffer de memória para carregar. Para lidar com arquivos grandes, use streaming. Veja Carregar arquivos grandes com streaming.
Confira a pasta StaticFileAuth do GitHub para ver a amostra completa.
Pesquisa no 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 no diretório com AddDirectoryBrowser e UseDirectoryBrowser:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/MyImages";
// Enable displaying browser links.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
O código anterior permite a navegação no diretório da pasta wwwroot/images usando a URL https://<hostname>/MyImages
, com links para cada arquivo e pasta:
AddDirectoryBrowser
adiciona serviços exigidos pelo middleware de pesquisa no 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 em todos os aplicativos.
Fornecer documentos padrão
Definir uma página padrão fornece aos visitantes um ponto de partida em um site. Para fornecer um arquivo padrão de wwwroot
sem exigir que a URL de solicitação para incluir o nome do arquivo, chame o método UseDefaultFiles:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
UseDefaultFiles
deve ser chamado antes de UseStaticFiles
para fornecer o arquivo padrão. UseDefaultFiles
é um regenerador de URL que não fornece o arquivo.
Com UseDefaultFiles
, as solicitações para uma pasta em wwwroot
pesquisam:
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. Por exemplo, no aplicativo de amostra, uma solicitação para https://localhost:<port>/def/
exibe default.html
de wwwroot/def
.
O seguinte código altera o nome do arquivo padrão para mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
UseFileServer para documentos padrão
UseFileServer combina a funcionalidade de UseStaticFiles
, UseDefaultFiles
e opcionalmente UseDirectoryBrowser
.
Chame app.UseFileServer
para habilitar o fornecimento de arquivos estáticos e o arquivo padrão. A navegação no diretório não está habilitada:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
O código a seguir permite o fornecimento de arquivos estáticos, do arquivo padrão e da navegação no diretório:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Considere a seguinte hierarquia de diretórios:
wwwroot
css
images
js
MyStaticFiles
defaultFiles
default.html
image3.png
images
MyImage.jpg
O código a seguir permite o fornecimento de arquivos estáticos, do arquivo padrão e da navegação no diretório de MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
AddDirectoryBrowser precisa ser chamado quando o valor da propriedade EnableDirectoryBrowsing
é true
.
Com o uso da hierarquia de arquivos anterior e do código, as URLs são resolvidas da seguinte maneira:
URI | Resposta |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
listagem de diretório |
https://<hostname>/StaticFiles/defaultFiles |
MyStaticFiles/defaultFiles/default.html |
https://<hostname>/StaticFiles/defaultFiles/image3.png |
MyStaticFiles/defaultFiles//image3.png |
Se nenhum arquivo nomeado como padrão existir no diretório MyStaticFiles, https://<hostname>/StaticFiles
retornará a listagem de diretórios com links clicáveis:
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://<hostname>/StaticFiles
para https://<hostname>/StaticFiles/
. As URLs relativas dentro do diretório StaticFiles são inválidas sem uma barra à direita (/
), a menos que a opção RedirectToAppendTrailingSlash de DefaultFilesOptions seja usada.
FileExtensionContentTypeProvider
A classe FileExtensionContentTypeProvider contém uma propriedade Mapeamentos que serve como um mapeamento de extensões de arquivo para tipos de conteúdo MIME. Na amostra a seguir, várias extensões de arquivo são mapeadas para tipos MIME conhecidos. A extensão .rtf é substituída e .mp4 é removida:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// 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
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
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 seguinte código habilita o fornecimento de tipos desconhecidos e renderiza o arquivo desconhecido como uma imagem:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Com o código anterior, uma solicitação para um arquivo com um tipo de conteúdo desconhecido é retornada como uma imagem.
Aviso
Habilitar ServeUnknownFileTypes é um risco à segurança. Ela está desabilitada por padrão, e seu uso não é recomendado. FileExtensionContentTypeProvider fornece uma alternativa mais segura para o fornecimento de arquivos com extensões não padrão.
Fornecer arquivos de vários locais
Considere a seguinte página Razor que exibe o arquivo /MyStaticFiles/image3.png
:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
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. O exemplo a seguir chama UseStaticFiles
duas vezes para fornecer arquivos de wwwroot
e MyStaticFiles
:
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Usando o código anterior:
- O arquivo
/MyStaticFiles/image3.png
é exibido. - Os auxiliares de marcação de imagem AppendVersion não são aplicados porque os auxiliares de marcação dependem de WebRootFileProvider.
WebRootFileProvider
não foi atualizado para incluir a pastaMyStaticFiles
.
O código a seguir atualiza o WebRootFileProvider
, que permite que o auxiliar de marcação de imagem forneça uma versão:
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider,
newPathProvider);
// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;
app.MapStaticAssets();
Observação
A abordagem anterior se aplica a Razor Pages e aplicativos MVC. Para obter diretrizes que se aplicam aos Blazor Web Apps, consulte Arquivos estáticos do ASP.NET Core Blazor.
Considerações de segurança para arquivos estáticos
Aviso
UseDirectoryBrowser
e UseStaticFiles
podem causar a perda de 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, Páginas do Razor, arquivos de configuração, etc.
As URLs para o conteúdo exposto com
UseDirectoryBrowser
,UseStaticFiles
eMapStaticAssets
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:
- Navegue para o recurso Módulos.
- Selecione StaticFileModule na lista.
- Clique em Remover na barra lateral Ações.
Aviso
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 arquivo web.config não foi 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.
Fornecer arquivos fora de wwwroot atualizando IWebHostEnvironment.WebRootPath
Quando IWebHostEnvironment.WebRootPath é definido como uma pasta diferente de wwwroot
:
- No ambiente de desenvolvimento, os ativos estáticos encontrados em
wwwroot
e os atualizadosIWebHostEnvironment.WebRootPath
são fornecidos dowwwroot
. - Em qualquer ambiente que não seja o desenvolvimento, ativos estáticos duplicados são fornecidos da pasta atualizada
IWebHostEnvironment.WebRootPath
.
Considere um aplicativo Web criado com o modelo da Web vazio:
Contendo um arquivo
Index.html
emwwwroot
ewwwroot-custom
.Com o seguinte arquivo
Program.cs
atualizado que defineWebRootPath = "wwwroot-custom"
:var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, // Look for static files in "wwwroot-custom" WebRootPath = "wwwroot-custom" }); var app = builder.Build(); app.UseDefaultFiles(); app.MapStaticAssets(); app.Run();
No código anterior, solicita /
:
- No ambiente de desenvolvimento retorna
wwwroot/Index.html
- Em qualquer ambiente que não seja o retorno do desenvolvimento
wwwroot-custom/Index.html
Para garantir que os ativos de wwwroot-custom
sejam retornados, use uma das seguintes abordagens:
Exclua ativos nomeados duplicados em
wwwroot
.Defina
"ASPNETCORE_ENVIRONMENT"
emProperties/launchSettings.json
para qualquer valor diferente de"Development"
.Desabilite completamente os ativos da Web estáticos definindo
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
no arquivo de projeto. AVISO, desabilitar ativos da Web estáticos desabilita Razor bibliotecas de classes.Adicione o seguinte XML ao arquivo do projeto:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
O código a seguir atualiza IWebHostEnvironment.WebRootPath
para um valor que não é de desenvolvimento, garantindo que o conteúdo duplicado seja retornado de wwwroot-custom
ao invés de wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.MapStaticAssets();
app.Run();
Recursos adicionais
Por Rick Anderson
Arquivos estáticos, como HTML, CSS, imagens e JavaScript, são ativos que um aplicativo ASP.NET Core fornece diretamente para os clientes por padrão.
Fornecer arquivos estáticos
Os arquivos estáticos são armazenados no diretório raiz Web do projeto. O diretório padrão é {content root}/wwwroot
, mas pode ser alterado com o método UseWebRoot. Para obter mais informações, consulte Raiz de conteúdo e Raiz web.
O método CreateBuilder define a raiz do conteúdo como o diretório atual:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Os arquivos estáticos são acessíveis por meio de um caminho relativo à raiz Web. Por exemplo, os modelos de projeto do Aplicativo Web contêm várias pastas dentro da pasta wwwroot
:
wwwroot
css
js
lib
Considere criar a pasta wwwroot/images e adicionar o arquivo wwwroot/images/MyImage.jpg
. O formato de URI para acessar um arquivo na pasta images
é https://<hostname>/images/<image_file_name>
. Por exemplo, https://localhost:5001/images/MyImage.jpg
Fornecer arquivos na raiz Web
Os modelos de aplicativo Web padrão chamam o método UseStaticFiles no Program.cs
, que permite que arquivos estáticos sejam fornecidos:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
A sobrecarga do método UseStaticFiles
sem parâmetro marca os arquivos raiz Web como fornecíveis. As seguintes referências de marcação wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Na marcação anterior, o caractere ~
de til aponta para a raiz Web.
Fornecer arquivos fora do diretório base
Considere uma hierarquia de diretórios na qual os arquivos estáticos a serem fornecidos residam fora da raiz Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Uma solicitação pode acessar o arquivo red-rose.jpg
configurando o middleware de arquivo estático da seguinte maneira:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
No código anterior, a hierarquia de diretórios MyStaticFiles é exposta publicamente por meio do segmento do URI StaticFiles. Uma solicitação para https://<hostname>/StaticFiles/images/red-rose.jpg
fornece ao arquivo red-rose.jpg
.
As seguintes referências de marcação MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Para fornecer arquivos de vários locais, consulte Fornecer arquivos de vários locais.
Definir cabeçalhos de resposta HTTP
Um objeto StaticFileOptions pode ser usado para definir cabeçalhos de resposta HTTP. Além de configurar o fornecimento de arquivo estático da raiz Web, o seguinte código define o cabeçalho de controle por cache:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
O código anterior disponibiliza arquivos estáticos publicamente no cache local por uma semana (604800 segundos).
Autorização de arquivo estático
Os modelos de ASP.NET Core chamam 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 fornecidos pelo Middleware de arquivo estático, como aqueles em
wwwroot
, são acessíveis publicamente.
Para fornecer arquivos estáticos com base na autorização:
- Armazene-os fora de
wwwroot
. - Chame
UseStaticFiles
, especificando um caminho, depois de chamarUseAuthorization
. - Defina a política de autorização de fallback.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using StaticFileAuth.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.MapRazorPages();
app.Run();
No código anterior, a política de autorização de fallback exige que todos os usuários sejam autenticados. Pontos de extremidade, como controladores, Páginas do Razor etc., que especificam seus próprios requisitos de autorização não usam a política de autorização de fallback. 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 em wwwroot
são acessíveis publicamente porque o middleware de arquivo estático padrão (app.UseStaticFiles();
) é chamado antes de UseAuthentication
. Os ativos estáticos na pasta MyStaticFiles exigem autenticação. O código de amostra demonstra isso.
Uma abordagem alternativa para fornecer arquivos com base na autorização é:
Armazene-os fora do
wwwroot
e de qualquer diretório acessível ao middleware de arquivo estático.Forneça-os por meio de um método de ação ao qual a autorização é aplicada e retorne um objeto FileResult:
[Authorize] public class BannerImageModel : PageModel { private readonly IWebHostEnvironment _env; public BannerImageModel(IWebHostEnvironment env) => _env = env; public PhysicalFileResult OnGet() { var filePath = Path.Combine( _env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg"); return PhysicalFile(filePath, "image/jpeg"); } }
A abordagem anterior exige uma página ou um ponto de extremidade por arquivo. O seguinte código retorna ou carrega arquivos para os usuários autenticados:
app.MapGet("/files/{fileName}", IResult (string fileName) =>
{
var filePath = GetOrCreateFilePath(fileName);
if (File.Exists(filePath))
{
return TypedResults.PhysicalFile(filePath, fileDownloadName: $"{fileName}");
}
return TypedResults.NotFound("No file found with the supplied file name");
})
.WithName("GetFileByName")
.RequireAuthorization("AuthenticatedUsers");
// IFormFile uses memory buffer for uploading. For handling large file use streaming instead.
// https://learn.microsoft.com/aspnet/core/mvc/models/file-uploads#upload-large-files-with-streaming
app.MapPost("/files", async (IFormFile file, LinkGenerator linker, HttpContext context) =>
{
// Don't rely on the file.FileName as it is only metadata that can be manipulated by the end-user
// Take a look at 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");
app.Run();
Confira a pasta StaticFileAuth do GitHub para ver a amostra completa.
Pesquisa no 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 no diretório com AddDirectoryBrowser e UseDirectoryBrowser:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/MyImages";
// Enable displaying browser links.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
O código anterior permite a navegação no diretório da pasta wwwroot/images usando a URL https://<hostname>/MyImages
, com links para cada arquivo e pasta:
AddDirectoryBrowser
adiciona serviços exigidos pelo middleware de pesquisa no 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 em todos os aplicativos.
Fornecer documentos padrão
Definir uma página padrão fornece aos visitantes um ponto de partida em um site. Para fornecer um arquivo padrão de wwwroot
sem exigir que a URL de solicitação para incluir o nome do arquivo, chame o método UseDefaultFiles:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseDefaultFiles
deve ser chamado antes de UseStaticFiles
para fornecer o arquivo padrão. UseDefaultFiles
é um regenerador de URL que não fornece o arquivo.
Com UseDefaultFiles
, as solicitações para uma pasta em wwwroot
pesquisam:
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 mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseFileServer para documentos padrão
UseFileServer combina a funcionalidade de UseStaticFiles
, UseDefaultFiles
e opcionalmente UseDirectoryBrowser
.
Chame app.UseFileServer
para habilitar o fornecimento de arquivos estáticos e o arquivo padrão. A navegação no diretório não está habilitada:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
O código a seguir permite o fornecimento de arquivos estáticos, do arquivo padrão e da navegação no diretório:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Considere a seguinte hierarquia de diretórios:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
O código a seguir permite o fornecimento de arquivos estáticos, do arquivo padrão e da navegação no diretório de MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
AddDirectoryBrowser precisa ser chamado quando o valor da propriedade EnableDirectoryBrowsing
é true
.
Com o uso da hierarquia de arquivos anterior e do código, as URLs são resolvidas da seguinte maneira:
URI | Resposta |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Se nenhum arquivo nomeado como padrão existir no diretório MyStaticFiles, https://<hostname>/StaticFiles
retornará a listagem de diretórios com links clicáveis:
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://<hostname>/StaticFiles
para https://<hostname>/StaticFiles/
. As URLs relativas dentro do diretório StaticFiles são inválidas sem uma barra à direita (/
), a menos que a opção RedirectToAppendTrailingSlash de DefaultFilesOptions seja usada.
FileExtensionContentTypeProvider
A classe FileExtensionContentTypeProvider contém uma propriedade Mappings
que fornece como um mapeamento de extensões de arquivo para tipos de conteúdo MIME. Na amostra a seguir, várias extensões de arquivo são mapeadas para tipos MIME conhecidos. A extensão .rtf é substituída e .mp4 é removida:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// 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
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
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 seguinte código habilita o fornecimento de tipos desconhecidos e renderiza o arquivo desconhecido como uma imagem:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Com o código anterior, uma solicitação para um arquivo com um tipo de conteúdo desconhecido é retornada como uma imagem.
Aviso
Habilitar ServeUnknownFileTypes é um risco à segurança. Ela está desabilitada por padrão, e seu uso não é recomendado. FileExtensionContentTypeProvider fornece uma alternativa mais segura para o fornecimento de arquivos com extensões não padrão.
Fornecer arquivos de vários locais
Considere a seguinte página Razor que exibe o arquivo /MyStaticFiles/image3.png
:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
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. O exemplo a seguir chama UseStaticFiles
duas vezes para fornecer arquivos de wwwroot
e MyStaticFiles
:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Usando o código anterior:
- O arquivo
/MyStaticFiles/image3.png
é exibido. - Os auxiliares de marcação de imagem AppendVersion não são aplicados porque os auxiliares de marcação dependem de WebRootFileProvider.
WebRootFileProvider
não foi atualizado para incluir a pastaMyStaticFiles
.
O código a seguir atualiza o WebRootFileProvider
, que permite que o auxiliar de marcação de imagem forneça uma versão:
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider,
newPathProvider);
// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;
app.UseStaticFiles();
Observação
A abordagem anterior se aplica a Razor Pages e aplicativos MVC. Para obter diretrizes que se aplicam aos Blazor Web Apps, consulte Arquivos estáticos do ASP.NET Core Blazor.
Considerações de segurança para arquivos estáticos
Aviso
UseDirectoryBrowser
e UseStaticFiles
podem causar a perda de 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, Páginas do Razor, arquivos de configuração, etc.
As URLs para o conteúdo exposto com
UseDirectoryBrowser
eUseStaticFiles
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:
- Navegue para o recurso Módulos.
- Selecione StaticFileModule na lista.
- Clique em Remover na barra lateral Ações.
Aviso
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 arquivo web.config não foi 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.
Fornecer arquivos fora de wwwroot atualizando IWebHostEnvironment.WebRootPath
Quando IWebHostEnvironment.WebRootPath é definido como uma pasta diferente de wwwroot
:
- No ambiente de desenvolvimento, os ativos estáticos encontrados em
wwwroot
e os atualizadosIWebHostEnvironment.WebRootPath
são fornecidos dowwwroot
. - Em qualquer ambiente que não seja o desenvolvimento, ativos estáticos duplicados são fornecidos da pasta atualizada
IWebHostEnvironment.WebRootPath
.
Considere um aplicativo Web criado com o modelo da Web vazio:
Contendo um arquivo
Index.html
emwwwroot
ewwwroot-custom
.Com o seguinte arquivo
Program.cs
atualizado que defineWebRootPath = "wwwroot-custom"
:var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, // Look for static files in "wwwroot-custom" WebRootPath = "wwwroot-custom" }); var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles(); app.Run();
No código anterior, solicita /
:
- No ambiente de desenvolvimento retorna
wwwroot/Index.html
- Em qualquer ambiente que não seja o retorno do desenvolvimento
wwwroot-custom/Index.html
Para garantir que os ativos de wwwroot-custom
sejam retornados, use uma das seguintes abordagens:
Exclua ativos nomeados duplicados em
wwwroot
.Defina
"ASPNETCORE_ENVIRONMENT"
emProperties/launchSettings.json
para qualquer valor diferente de"Development"
.Desabilite completamente os ativos da Web estáticos definindo
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
no arquivo de projeto. AVISO, desabilitar ativos da Web estáticos desabilita Razor bibliotecas de classes.Adicione o seguinte JSON ao arquivo de projeto:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
O código a seguir atualiza IWebHostEnvironment.WebRootPath
para um valor que não é de desenvolvimento, garantindo que o conteúdo duplicado seja retornado de wwwroot-custom
ao invés de wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();
Recursos adicionais
Por Rick Anderson e Kirk Larkin
Arquivos estáticos, como HTML, CSS, imagens e JavaScript, são ativos que um aplicativo ASP.NET Core fornece diretamente para os clientes por padrão.
Fornecer arquivos estáticos
Os arquivos estáticos são armazenados no diretório raiz Web do projeto. O diretório padrão é {content root}/wwwroot
, mas pode ser alterado com o método UseWebRoot. Para obter mais informações, consulte Raiz de conteúdo e Raiz web.
O método CreateBuilder define a raiz do conteúdo como o diretório atual:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Os arquivos estáticos são acessíveis por meio de um caminho relativo à raiz Web. Por exemplo, os modelos de projeto do Aplicativo Web contêm várias pastas dentro da pasta wwwroot
:
wwwroot
css
js
lib
Considere criar a pasta wwwroot/images e adicionar o arquivo wwwroot/images/MyImage.jpg
. O formato de URI para acessar um arquivo na pasta images
é https://<hostname>/images/<image_file_name>
. Por exemplo, https://localhost:5001/images/MyImage.jpg
Fornecer arquivos na raiz Web
Os modelos de aplicativo Web padrão chamam o método UseStaticFiles no Program.cs
, que permite que arquivos estáticos sejam fornecidos:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
A sobrecarga do método UseStaticFiles
sem parâmetro marca os arquivos raiz Web como fornecíveis. As seguintes referências de marcação wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Na marcação anterior, o caractere ~
de til aponta para a raiz Web.
Fornecer arquivos fora do diretório base
Considere uma hierarquia de diretórios na qual os arquivos estáticos a serem fornecidos residam fora da raiz Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Uma solicitação pode acessar o arquivo red-rose.jpg
configurando o middleware de arquivo estático da seguinte maneira:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
No código anterior, a hierarquia de diretórios MyStaticFiles é exposta publicamente por meio do segmento do URI StaticFiles. Uma solicitação para https://<hostname>/StaticFiles/images/red-rose.jpg
fornece ao arquivo red-rose.jpg
.
As seguintes referências de marcação MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Para fornecer arquivos de vários locais, consulte Fornecer arquivos de vários locais.
Definir cabeçalhos de resposta HTTP
Um objeto StaticFileOptions pode ser usado para definir cabeçalhos de resposta HTTP. Além de configurar o fornecimento de arquivo estático da raiz Web, o seguinte código define o cabeçalho de controle por cache:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
O código anterior disponibiliza arquivos estáticos publicamente no cache local por uma semana (604800 segundos).
Autorização de arquivo estático
Os modelos de ASP.NET Core chamam 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 fornecidos pelo Middleware de arquivo estático, como aqueles em
wwwroot
, são acessíveis publicamente.
Para fornecer arquivos estáticos com base na autorização:
- Armazene-os fora de
wwwroot
. - Chame
UseStaticFiles
, especificando um caminho, depois de chamarUseAuthorization
. - Defina a política de autorização de fallback.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using StaticFileAuth.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.MapRazorPages();
app.Run();
No código anterior, a política de autorização de fallback exige que todos os usuários sejam autenticados. Pontos de extremidade, como controladores, Páginas do Razor etc., que especificam seus próprios requisitos de autorização não usam a política de autorização de fallback. 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 em wwwroot
são acessíveis publicamente porque o middleware de arquivo estático padrão (app.UseStaticFiles();
) é chamado antes de UseAuthentication
. Os ativos estáticos na pasta MyStaticFiles exigem autenticação. O código de amostra demonstra isso.
Uma abordagem alternativa para fornecer arquivos com base na autorização é:
- Armazene-os fora do
wwwroot
e de qualquer diretório acessível ao middleware de arquivo estático. - Forneça-os por meio de um método de ação ao qual a autorização é aplicada e retorne um objeto FileResult:
[Authorize]
public class BannerImageModel : PageModel
{
private readonly IWebHostEnvironment _env;
public BannerImageModel(IWebHostEnvironment env) =>
_env = env;
public PhysicalFileResult OnGet()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
}
Pesquisa no 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 no diretório com AddDirectoryBrowser e UseDirectoryBrowser:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/MyImages";
// Enable displaying browser links.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
O código anterior permite a navegação no diretório da pasta wwwroot/images usando a URL https://<hostname>/MyImages
, com links para cada arquivo e pasta:
AddDirectoryBrowser
adiciona serviços exigidos pelo middleware de pesquisa no 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 em todos os aplicativos.
Fornecer documentos padrão
Definir uma página padrão fornece aos visitantes um ponto de partida em um site. Para fornecer um arquivo padrão de wwwroot
sem exigir que a URL de solicitação para incluir o nome do arquivo, chame o método UseDefaultFiles:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseDefaultFiles
deve ser chamado antes de UseStaticFiles
para fornecer o arquivo padrão. UseDefaultFiles
é um regenerador de URL que não fornece o arquivo.
Com UseDefaultFiles
, as solicitações para uma pasta em wwwroot
pesquisam:
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 mydefault.html
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
UseFileServer para documentos padrão
UseFileServer combina a funcionalidade de UseStaticFiles
, UseDefaultFiles
e opcionalmente UseDirectoryBrowser
.
Chame app.UseFileServer
para habilitar o fornecimento de arquivos estáticos e o arquivo padrão. A navegação no diretório não está habilitada:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
O código a seguir permite o fornecimento de arquivos estáticos, do arquivo padrão e da navegação no diretório:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Considere a seguinte hierarquia de diretórios:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
O código a seguir permite o fornecimento de arquivos estáticos, do arquivo padrão e da navegação no diretório de MyStaticFiles
:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
AddDirectoryBrowser precisa ser chamado quando o valor da propriedade EnableDirectoryBrowsing
é true
.
Com o uso da hierarquia de arquivos anterior e do código, as URLs são resolvidas da seguinte maneira:
URI | Resposta |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Se nenhum arquivo nomeado como padrão existir no diretório MyStaticFiles, https://<hostname>/StaticFiles
retornará a listagem de diretórios com links clicáveis:
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://<hostname>/StaticFiles
para https://<hostname>/StaticFiles/
. As URLs relativas dentro do diretório StaticFiles são inválidas sem uma barra à direita (/
), a menos que a opção RedirectToAppendTrailingSlash de DefaultFilesOptions seja usada.
FileExtensionContentTypeProvider
A classe FileExtensionContentTypeProvider contém uma propriedade Mappings
que fornece como um mapeamento de extensões de arquivo para tipos de conteúdo MIME. Na amostra a seguir, várias extensões de arquivo são mapeadas para tipos MIME conhecidos. A extensão .rtf é substituída e .mp4 é removida:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// 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
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
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 seguinte código habilita o fornecimento de tipos desconhecidos e renderiza o arquivo desconhecido como uma imagem:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Com o código anterior, uma solicitação para um arquivo com um tipo de conteúdo desconhecido é retornada como uma imagem.
Aviso
Habilitar ServeUnknownFileTypes é um risco à segurança. Ela está desabilitada por padrão, e seu uso não é recomendado. FileExtensionContentTypeProvider fornece uma alternativa mais segura para o fornecimento de arquivos com extensões não padrão.
Fornecer arquivos de vários locais
Considere a seguinte página Razor que exibe o arquivo /MyStaticFiles/image3.png
:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
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. O exemplo a seguir chama UseStaticFiles
duas vezes para fornecer arquivos de wwwroot
e MyStaticFiles
:
app.UseStaticFiles(); // Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Usando o código anterior:
- O arquivo
/MyStaticFiles/image3.png
é exibido. - Os auxiliares de marcação de imagem AppendVersion não são aplicados porque os auxiliares de marcação dependem de WebRootFileProvider.
WebRootFileProvider
não foi atualizado para incluir a pastaMyStaticFiles
.
O código a seguir atualiza o WebRootFileProvider
, que permite que o auxiliar de marcação de imagem forneça uma versão:
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider,
newPathProvider);
// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;
app.UseStaticFiles();
Considerações de segurança para arquivos estáticos
Aviso
UseDirectoryBrowser
e UseStaticFiles
podem causar a perda de 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, Páginas do Razor, arquivos de configuração, etc.
As URLs para o conteúdo exposto com
UseDirectoryBrowser
eUseStaticFiles
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:
- Navegue para o recurso Módulos.
- Selecione StaticFileModule na lista.
- Clique em Remover na barra lateral Ações.
Aviso
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 arquivo web.config não foi 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.
Fornecer arquivos fora de wwwroot atualizando IWebHostEnvironment.WebRootPath
Quando IWebHostEnvironment.WebRootPath é definido como uma pasta diferente de wwwroot
:
- No ambiente de desenvolvimento, os ativos estáticos encontrados em
wwwroot
e os atualizadosIWebHostEnvironment.WebRootPath
são fornecidos dowwwroot
. - Em qualquer ambiente que não seja o desenvolvimento, ativos estáticos duplicados são fornecidos da pasta atualizada
IWebHostEnvironment.WebRootPath
.
Considere um aplicativo Web criado com o modelo da Web vazio:
Contendo um arquivo
Index.html
emwwwroot
ewwwroot-custom
.Com o seguinte arquivo
Program.cs
atualizado que defineWebRootPath = "wwwroot-custom"
:var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, // Look for static files in "wwwroot-custom" WebRootPath = "wwwroot-custom" }); var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles(); app.Run();
No código anterior, solicita /
:
- No ambiente de desenvolvimento retorna
wwwroot/Index.html
- Em qualquer ambiente que não seja o retorno do desenvolvimento
wwwroot-custom/Index.html
Para garantir que os ativos de wwwroot-custom
sejam retornados, use uma das seguintes abordagens:
Exclua ativos nomeados duplicados em
wwwroot
.Defina
"ASPNETCORE_ENVIRONMENT"
emProperties/launchSettings.json
para qualquer valor diferente de"Development"
.Desabilite completamente os ativos da Web estáticos definindo
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
no arquivo de projeto. AVISO, desabilitar ativos da Web estáticos desabilita Razor bibliotecas de classes.Adicione o seguinte JSON ao arquivo de projeto:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
O código a seguir atualiza IWebHostEnvironment.WebRootPath
para um valor que não é de desenvolvimento, garantindo que o conteúdo duplicado seja retornado de wwwroot-custom
ao invés de wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();
Recursos adicionais
Por Rick Anderson e Kirk Larkin
Arquivos estáticos, como HTML, CSS, imagens e JavaScript, são ativos que um aplicativo ASP.NET Core fornece diretamente para os clientes por padrão.
Exibir ou baixar código de exemplo (como baixar)
Fornecer arquivos estáticos
Os arquivos estáticos são armazenados no diretório raiz Web do projeto. O diretório padrão é {content root}/wwwroot
, mas pode ser alterado com o método UseWebRoot. Para obter mais informações, consulte Raiz de conteúdo e Raiz web.
O método CreateDefaultBuilder define a raiz do conteúdo como o diretório atual:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
O código anterior foi criado com o modelo de aplicativo Web.
Os arquivos estáticos são acessíveis por meio de um caminho relativo à raiz Web. Por exemplo, os modelos de projeto do Aplicativo Web contêm várias pastas dentro da pasta wwwroot
:
wwwroot
css
js
lib
Considere criar a pasta wwwroot/images e adicionar o arquivo wwwroot/images/MyImage.jpg
. O formato de URI para acessar um arquivo na pasta images
é https://<hostname>/images/<image_file_name>
. Por exemplo, https://localhost:5001/images/MyImage.jpg
Fornecer arquivos na raiz Web
Os modelos de aplicativo Web padrão chamam o método UseStaticFiles no Startup.Configure
, que permite que arquivos estáticos sejam fornecidos:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
A sobrecarga do método UseStaticFiles
sem parâmetro marca os arquivos raiz Web como fornecíveis. As seguintes referências de marcação wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
No código anterior, o caractere til ~/
aponta para a raiz Web.
Fornecer arquivos fora do diretório base
Considere uma hierarquia de diretórios na qual os arquivos estáticos a serem fornecidos residam fora da raiz Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Uma solicitação pode acessar o arquivo red-rose.jpg
configurando o middleware de arquivo estático da seguinte maneira:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
No código anterior, a hierarquia de diretórios MyStaticFiles é exposta publicamente por meio do segmento do URI StaticFiles. Uma solicitação para https://<hostname>/StaticFiles/images/red-rose.jpg
fornece ao arquivo red-rose.jpg
.
As seguintes referências de marcação MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Definir cabeçalhos de resposta HTTP
Um objeto StaticFileOptions pode ser usado para definir cabeçalhos de resposta HTTP. Além de configurar o fornecimento de arquivo estático da raiz Web, o seguinte código define o cabeçalho Cache-Control
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
const string cacheMaxAge = "604800";
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
// using Microsoft.AspNetCore.Http;
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAge}");
}
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
O código anterior define a idade máxima como 604800 segundos (7 dias).
Autorização de arquivo estático
Os modelos de ASP.NET Core chamam 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 fornecidos pelo Middleware de arquivo estático, como aqueles em
wwwroot
, são acessíveis publicamente.
Para fornecer arquivos estáticos com base na autorização:
- Armazene-os fora de
wwwroot
. - Chame
UseStaticFiles
, especificando um caminho, depois de chamarUseAuthorization
. - Defina a política de autorização de fallback.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
}
// Remaining code ommitted for brevity.
No código anterior, a política de autorização de fallback exige que todos os usuários sejam autenticados. Pontos de extremidade, como controladores, Páginas do Razor etc., que especificam seus próprios requisitos de autorização não usam a política de autorização de fallback. 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 em wwwroot
são acessíveis publicamente porque o middleware de arquivo estático padrão (app.UseStaticFiles();
) é chamado antes de UseAuthentication
. Os ativos estáticos na pasta MyStaticFiles exigem autenticação. O código de amostra demonstra isso.
Uma abordagem alternativa para fornecer arquivos com base na autorização é:
- Armazene-os fora do
wwwroot
e de qualquer diretório acessível ao middleware de arquivo estático. - Forneça-os por meio de um método de ação ao qual a autorização é aplicada e retorne um objeto FileResult:
[Authorize]
public IActionResult BannerImage()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
Pesquisa no 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 no diretório com:
- AddDirectoryBrowser em
Startup.ConfigureServices
. - UseDirectoryBrowser em
Startup.Configure
.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
O código anterior permite a navegação no diretório da pasta wwwroot/images usando a URL https://<hostname>/MyImages
, com links para cada arquivo e pasta:
Fornecer documentos padrão
Definir uma página padrão fornece aos visitantes um ponto de partida em um site. Para fornecer um arquivo padrão de wwwroot
sem exigir que a URL de solicitação para incluir o nome do arquivo, chame o método UseDefaultFiles:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
UseDefaultFiles
deve ser chamado antes de UseStaticFiles
para fornecer o arquivo padrão. UseDefaultFiles
é um regenerador de URL que não fornece o arquivo.
Com UseDefaultFiles
, as solicitações para uma pasta em wwwroot
pesquisam:
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 mydefault.html
:
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
O código a seguir mostra Startup.Configure
com o código anterior:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
UseFileServer para documentos padrão
UseFileServer combina a funcionalidade de UseStaticFiles
, UseDefaultFiles
e opcionalmente UseDirectoryBrowser
.
Chame app.UseFileServer
para habilitar o fornecimento de arquivos estáticos e o arquivo padrão. A navegação no diretório não está habilitada. O código a seguir mostra Startup.Configure
com UseFileServer
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
O código a seguir permite o fornecimento de arquivos estáticos, do arquivo padrão e da navegação no diretório:
app.UseFileServer(enableDirectoryBrowsing: true);
O código a seguir mostra Startup.Configure
com o código anterior:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseFileServer(enableDirectoryBrowsing: true);
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Considere a seguinte hierarquia de diretórios:
wwwroot
css
images
js
MyStaticFiles
images
MyImage.jpg
default.html
O código a seguir permite o fornecimento de arquivos estáticos, do arquivo padrão e da navegação no diretório de MyStaticFiles
:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(); // For the wwwroot folder.
// using Microsoft.Extensions.FileProviders;
// using System.IO;
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
AddDirectoryBrowser precisa ser chamado quando o valor da propriedade EnableDirectoryBrowsing
é true
.
Com o uso da hierarquia de arquivos e do código anterior, as URLs são resolvidas da seguinte maneira:
URI | Resposta |
---|---|
https://<hostname>/StaticFiles/images/MyImage.jpg |
MyStaticFiles/images/MyImage.jpg |
https://<hostname>/StaticFiles |
MyStaticFiles/default.html |
Se nenhum arquivo nomeado como padrão existir no diretório MyStaticFiles, https://<hostname>/StaticFiles
retornará a listagem de diretórios com links clicáveis:
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://<hostname>/StaticFiles
para https://<hostname>/StaticFiles/
. As URLs relativas dentro do diretório StaticFiles são inválidas sem uma barra à direita (/
).
FileExtensionContentTypeProvider
A classe FileExtensionContentTypeProvider contém uma propriedade Mappings
que fornece como um mapeamento de extensões de arquivo para tipos de conteúdo MIME. Na amostra a seguir, várias extensões de arquivo são mapeadas para tipos MIME conhecidos. A extensão .rtf é substituída e .mp4 é removida:
// 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 = "/MyImages",
ContentTypeProvider = provider
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
O código a seguir mostra Startup.Configure
com o código anterior:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// 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 = "/MyImages",
ContentTypeProvider = provider
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
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 seguinte código habilita o fornecimento de tipos desconhecidos e renderiza o arquivo desconhecido como uma imagem:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
O código a seguir mostra Startup.Configure
com o código anterior:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
Com o código anterior, uma solicitação para um arquivo com um tipo de conteúdo desconhecido é retornada como uma imagem.
Aviso
Habilitar ServeUnknownFileTypes é um risco à segurança. Ela está desabilitada por padrão, e seu uso não é recomendado. FileExtensionContentTypeProvider fornece uma alternativa mais segura para o fornecimento de arquivos com extensões não padrão.
Fornecer arquivos de vários locais
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. Saiba mais neste tópico do GitHub.
Considerações de segurança para arquivos estáticos
Aviso
UseDirectoryBrowser
e UseStaticFiles
podem causar a perda de 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, Páginas do Razor, arquivos de configuração, etc.
As URLs para o conteúdo exposto com
UseDirectoryBrowser
eUseStaticFiles
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:
- Navegue para o recurso Módulos.
- Selecione StaticFileModule na lista.
- Clique em Remover na barra lateral Ações.
Aviso
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 arquivo web.config não foi 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.