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.
Advertência
Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.
Importante
Estas informações referem-se a um produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece garantias, expressas ou implícitas, em relação à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 serve diretamente aos clientes por padrão.
Para orientação sobre Blazor arquivos estáticos, que adiciona ou substitui a orientação neste artigo, consulte arquivos estáticos do ASP.NET Core Blazor.
Servir arquivos estáticos
Os arquivos estáticos são armazenados dentro do diretório raiz web do projeto {content root}/wwwroot
, mas pode ser alterado com o método UseWebRoot. Para obter mais informações, consulte raiz de Conteúdo e raiz da Web.
O método CreateBuilder define a raiz do conteúdo para 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 através de um caminho relativo à raiz webdo wwwroot
:
wwwroot
css
js
lib
Considere um aplicativo com o arquivo wwwroot/images/MyImage.jpg
. O formato 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 de alto desempenho requer a otimização da entrega de ativos para o navegador. As otimizações possíveis incluem:
- Sirva um determinado ativo uma vez até que o arquivo seja alterado ou o navegador limpe seu cache. Defina o cabeçalho ETag.
- Impeça que o navegador use ativos antigos ou obsoletos depois que um aplicativo for atualizado. Defina o cabeçalho Última modificação.
- Configure cabeçalhos de cache de adequados.
- Use middleware de cache.
- Sirva versões comprimidas dos ficheiros sempre que possível.
- Use um CDN para servir os ativos mais próximos do usuário.
- Minimize o tamanho dos recursos servidos ao navegador. Esta otimização não inclui a minificação.
- Integra as informações coletadas sobre ativos da Web estáticos durante o processo de compilação ou publicação com uma biblioteca de tempo de execução que processa essas informações para otimizar o serviço de arquivos para o navegador.
- São convenções de endpoint de roteamento que otimizam a entrega de ativos estáticos numa aplicação. Ele foi projetado para funcionar com todas as estruturas de interface do usuário, incluindo Blazor, Razor Pages e MVC.
UseStaticFiles
também serve arquivos estáticos, mas não fornece o mesmo nível de otimização que MapStaticAssets
. Para obter uma comparação entre UseStaticFiles
e MapStaticAssets
, consulte Otimizando a entrega de ativos da Web estáticos .
Servir arquivos na raiz da Web
Os modelos de aplicativo Web padrão chamam o método MapStaticAssets no Program.cs
, que permite que arquivos estáticos sejam servidos:
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 de método UseStaticFiles
sem parâmetros marca os arquivos em raiz da Web como servíveis. As marcações seguintes referem-se a wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Na marcação anterior, o caractere til ~
aponta para a raiz da Web .
Servir arquivos fora da raiz da web
Considere uma hierarquia de diretórios na qual os arquivos estáticos a serem servidos residem fora da raiz da 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, o MyStaticFiles hierarquia de diretórios é exposto publicamente por meio do segmento StaticFiles URI. Um pedido de https://<hostname>/StaticFiles/images/red-rose.jpg
serve o ficheiro red-rose.jpg
.
As seguintes marcações referentes a MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Para servir ficheiros a partir de várias localizações, consulte Servir ficheiros a partir de várias localizações.
Definir cabeçalhos de resposta HTTP
Um objeto StaticFileOptions pode ser usado para definir cabeçalhos de resposta HTTP. Além de configurar o serviço de arquivos estáticos a partir do
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 torna os arquivos estáticos disponíveis publicamente no cache local por uma semana.
Autorização de arquivo estático
Os modelos ASP.NET Core chamam MapStaticAssets antes de chamar UseAuthorization. A maioria das aplicações segue este padrão. Quando o middleware de ficheiro estático é chamado antes do middleware de autenticação:
- Nenhuma verificação de autorização é executada nos arquivos estáticos.
- Os arquivos estáticos servidos pelo Static File Middleware, como aqueles em
wwwroot
, são acessíveis publicamente.
Para servir 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 todos os usuários sejam autenticados. Pontos de extremidade, como controladores, Razor Pages, etc., que especificam os seus próprios requisitos de autorização não utilizam a política de autorização de fallback. Por exemplo, Razor Pages, 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, o que impõe que o usuário atual seja autenticado.
Os ativos estáticos sob wwwroot
são acessíveis publicamente porque a Middleware de Ficheiros Estáticos padrão (app.UseStaticFiles();
) é chamada antes de UseAuthentication
. Os ativos estáticos na pasta
Uma abordagem alternativa para servir ficheiros com base na autorização é:
Armazene-os fora do
wwwroot
e de qualquer diretório acessível ao Static File Middleware.Sirva-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 requer uma página ou endpoint por ficheiro. O código a seguir retorna arquivos ou carrega arquivos para 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 buffer de memória para upload. Para lidar com arquivos grandes, use o streaming. Consulte Carregar ficheiros grandes com streaming.
Consulte o StaticFileAuth pasta GitHub para obter o exemplo completo.
Navegação no diretório
A navegação no diretório permite a listagem de diretórios dentro de diretórios especificados.
A navegação no diretório é desativada por padrão por motivos de segurança. Para obter mais informações, consulte Considerações de segurança para 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 do pasta wwwroot/images usando o URL https://<hostname>/MyImages
, com links para cada arquivo e pasta:
AddDirectoryBrowser
adiciona serviços exigidos pelo middleware de navegação no diretório, incluindo HtmlEncoder. Esses serviços podem ser adicionados por outras chamadas, como AddRazorPages, mas recomendamos ligar para AddDirectoryBrowser
para garantir que os serviços sejam adicionados em todos os aplicativos.
Servir documentos predefinidos
Definir uma página padrão fornece aos visitantes um ponto de partida em um site. Para servir um arquivo padrão do wwwroot
sem exigir que a URL da solicitação inclua 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 UseStaticFiles
para servir o arquivo padrão.
UseDefaultFiles
é um reescritor de URL que não serve o arquivo.
Com UseDefaultFiles
, as solicitações para uma pasta em wwwroot
procuram:
default.htm
default.html
index.htm
index.html
O primeiro arquivo encontrado na lista é servido como se a solicitação incluísse o nome do arquivo. O URL do navegador continua a refletir o URI solicitado. Por exemplo, noaplicativo de exemplo
O código a seguir altera o nome de 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 serviço de arquivos estáticos e o arquivo padrão. A navegação no diretório não está ativada:
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 serviço de arquivos estáticos, o arquivo padrão e a 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 serviço de arquivos estáticos, o arquivo padrão e a 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 deve ser chamado quando o valor EnableDirectoryBrowsing
da propriedade é true
.
Usando a hierarquia de arquivos e o código anteriores, 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órios |
https://<hostname>/StaticFiles/defaultFiles |
MyStaticFiles/defaultFiles/default.html |
https://<hostname>/StaticFiles/defaultFiles/image3.png |
MyStaticFiles/defaultFiles//image3.png |
Se não existir nenhum arquivo com nome padrão no diretório MyStaticFiles
UseDefaultFiles e UseDirectoryBrowser realizam um redirecionamento no lado do cliente do URI de destino sem um /
para o URI de destino com um /
. Por exemplo, de https://<hostname>/StaticFiles
para https://<hostname>/StaticFiles/
. URLs relativos dentro do diretório StaticFiles
FileExtensionContentTypeProvider
A classe FileExtensionContentTypeProvider contém uma propriedade Mappings que serve como um mapeamento de extensões de arquivo para tipos de conteúdo MIME. No exemplo 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 os tipos de conteúdo MIME indicados em .
Tipos de conteúdo não padrão
O Static File Middleware 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 passará a solicitação para o próximo middleware no pipeline. Se nenhum middleware lidar com a solicitação, uma resposta 404 Not Found será retornada. Se a navegação no diretório estiver habilitada, um link para o arquivo será exibido em uma listagem de diretório.
O código a seguir permite servir 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.
Advertência
Ativar ServeUnknownFileTypes é um risco de segurança. Ele está desativado por padrão, e seu uso é desencorajado. FileExtensionContentTypeProvider fornece uma alternativa mais segura ao serviço de arquivos com extensões não padrão.
Sirva arquivos de vários locais
Considere a seguinte página de 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 servir arquivos de outros locais. O exemplo a seguir chama UseStaticFiles
duas vezes para servir 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 Tag de Imagem AppendVersion não são aplicados porque os Auxiliares de Tag dependem de WebRootFileProvider.
WebRootFileProvider
não foi atualizado para incluir a pastaMyStaticFiles
.
O código a seguir atualiza o WebRootFileProvider
, que permite que o Image Tag Helper 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 aplica-se a Razor Pages e aplicativos MVC. Para obter orientações que se aplicam a Blazor Web Apps, consulte ASP.NET Core Blazor arquivos estáticos.
Considerações de segurança para arquivos estáticos
Advertência
UseDirectoryBrowser
e UseStaticFiles
podem vazar segredos. Desativar a navegação no diretório em produção é altamente recomendado. Analise cuidadosamente quais diretórios estão habilitados via UseStaticFiles
ou UseDirectoryBrowser
. Todo o diretório e seus subdiretórios tornam-se acessíveis ao público. Armazene arquivos adequados para servir ao público em um diretório dedicado, como <content_root>/wwwroot
. Separe esses arquivos de visualizações MVC, Razor Pages, arquivos de configuração, etc.
Os URLs para conteúdo exposto com
UseDirectoryBrowser
,UseStaticFiles
eMapStaticAssets
estão sujeitos às restrições de diferenciação de maiúsculas e minúsculas e caracteres do sistema de arquivos subjacente. Por exemplo, o Windows não diferencia maiúsculas de minúsculas, mas o macOS e o Linux não.ASP.NET aplicativos principais hospedados no IIS usam o do módulo principal do
ASP.NET para encaminhar todas as solicitações para o aplicativo, incluindo solicitações de arquivos estáticos. O manipulador de arquivos estáticos do IIS não é usado e não tem chance de lidar com solicitações. Conclua as seguintes etapas no Gerenciador do IIS para remover o manipulador de arquivos estáticos do IIS no nível do servidor ou do site:
- Navegue até a funcionalidade Módulos.
- Selecione StaticFileModule na lista.
- Clique Remover na barra lateral Ações.
Advertência
Se o manipulador de arquivos estáticos do IIS estiver habilitado e o módulo principal do ASP.NET estiver configurado incorretamente, os arquivos estáticos serão servidos. Isso acontece, por exemplo, se o arquivo web.config não for implantado.
- Coloque ficheiros de código, incluindo
e , fora da raiz webdo projeto da aplicação . 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 evita que o código do lado do servidor seja vazado.
Servir arquivos fora do wwwroot atualizando IWebHostEnvironment.WebRootPath
Quando IWebHostEnvironment.WebRootPath estiver definido para uma pasta diferente de wwwroot
:
- No ambiente de desenvolvimento, os ativos estáticos encontrados no
wwwroot
e noIWebHostEnvironment.WebRootPath
atualizado são servidos a partir dewwwroot
. - Em qualquer ambiente que não seja o de desenvolvimento, os ativos estáticos replicados são servidos a partir da pasta
IWebHostEnvironment.WebRootPath
atualizada.
Considere um aplicativo Web criado com o modelo da Web vazio:
Contendo um ficheiro
Index.html
nowwwroot
ewwwroot-custom
.Com o seguinte arquivo de
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, as requisições para /
:
- No ambiente de desenvolvimento retornar
wwwroot/Index.html
- Em qualquer ambiente que não seja o desenvolvimento, o retorno
wwwroot-custom/Index.html
Para garantir que os ativos de wwwroot-custom
sejam devolvidos, use uma das seguintes abordagens:
Exclua ativos com nome duplicados no
wwwroot
.Defina
"ASPNETCORE_ENVIRONMENT"
emProperties/launchSettings.json
para qualquer valor diferente de"Development"
.Desative completamente os ativos da Web estáticos definindo
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
no arquivo de projeto. AVISO, desactivar recursos estáticos da Web desabilita Razor Bibliotecas de Classes.Adicione o seguinte XML ao arquivo de projeto:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
A seguinte atualização do código IWebHostEnvironment.WebRootPath
para um valor que não é de desenvolvimento, garante que o conteúdo duplicado seja retornado de wwwroot-custom
em vez 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 serve diretamente aos clientes por padrão.
Servir arquivos estáticos
Os arquivos estáticos são armazenados dentro do diretório raiz da 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 da Web.
O método CreateBuilder define a raiz do conteúdo para 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 através de um caminho relativo ao raiz da web. Por exemplo, os modelos de projeto Aplicativo Web contêm várias pastas dentro da pasta wwwroot
:
wwwroot
css
js
lib
Considere criar a pasta de wwwroot/images e adicionar o ficheiro wwwroot/images/MyImage.jpg
. O formato URI para acessar um arquivo na pasta images
é https://<hostname>/images/<image_file_name>
. Por exemplo, https://localhost:5001/images/MyImage.jpg
Servir arquivos no diretório raiz da Web
Os modelos de aplicativo Web padrão chamam o método UseStaticFiles no Program.cs
, que permite que arquivos estáticos sejam servidos:
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 de método UseStaticFiles
sem parâmetros marca os arquivos na raiz Web como acessíveis. As referências de marcação a seguir referem-se a wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Na marcação anterior, o caractere til ~
aponta para a raiz da Web .
Servir arquivos fora da raiz da Web
Considere uma hierarquia de diretórios na qual os arquivos estáticos a serem servidos residem fora da raiz da 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 através do segmento URI StaticFiles. Um pedido de https://<hostname>/StaticFiles/images/red-rose.jpg
serve o ficheiro 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 servir ficheiros a partir de várias localizações, consulte Servir ficheiros a partir de várias localizações.
Definir cabeçalhos de resposta HTTP
Um objeto StaticFileOptions pode ser usado para definir cabeçalhos de resposta HTTP. Além de configurar o serviço de arquivos estáticos da raiz da Web , o código a seguir define o cabeçalho Cache-Control:
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 torna os arquivos estáticos publicamente disponíveis no cache local por uma semana (604800 segundos).
Autorização de arquivo estático
Os modelos ASP.NET Core chamam UseStaticFiles antes de chamar UseAuthorization. A maioria das aplicações segue este padrão. Quando o middleware de ficheiro estático é chamado antes do middleware de autorização:
- Nenhuma verificação de autorização é executada nos arquivos estáticos.
- Os arquivos estáticos servidos pelo Static File Middleware, como aqueles em
wwwroot
, são acessíveis publicamente.
Para servir arquivos estáticos com autorização:
- Armazene-os fora de
wwwroot
. - Chame
UseStaticFiles
, especificando um caminho, depois de chamarUseAuthorization
. - Defina a política de autorização 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 todos os usuários sejam autenticados. Pontos de extensão, como controladores, páginas Razor, etc., que especificam os seus próprios requisitos de autorização não usam a política de autorização predefinida. Por exemplo, Razor Páginas, controladores ou métodos de ação que contêm [AllowAnonymous]
ou [Authorize(PolicyName="MyPolicy")]
usam o atributo de autorização aplicado em vez da política de autorização padrão.
RequireAuthenticatedUser adiciona DenyAnonymousAuthorizationRequirement à instância atual, o que impõe que o usuário atual seja autenticado.
Os ativos estáticos sob 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
Uma abordagem alternativa para servir ficheiros com base na autorização é:
Armazene-os fora do
wwwroot
e de qualquer diretório acessível ao Static File Middleware.Servi-los por meio de um método de ação ao qual a autorização é aplicada e retornar 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 requer uma página ou endpoint por arquivo. O código a seguir retorna arquivos ou carrega arquivos para 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();
Consulte o StaticFileAuth pasta GitHub para obter o exemplo completo.
Navegação no diretório
A navegação no diretório permite a listagem de diretórios dentro de diretórios especificados.
A navegação no diretório é desativada por padrão por motivos de segurança. Para obter mais informações, consulte Considerações de segurança para 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 do pasta wwwroot/images usando o URL https://<hostname>/MyImages
, com links para cada arquivo e pasta:
AddDirectoryBrowser
adiciona serviços exigidos pelo middleware de navegação no diretório, incluindo HtmlEncoder. Esses serviços podem ser adicionados por outras chamadas, como AddRazorPages, mas recomendamos ligar para AddDirectoryBrowser
para garantir que os serviços sejam adicionados em todos os aplicativos.
Servir documentos por defeito
Definir uma página padrão fornece aos visitantes um ponto de partida em um site. Para servir um arquivo padrão do wwwroot
sem exigir que a URL da solicitação inclua 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 UseStaticFiles
para servir o arquivo padrão.
UseDefaultFiles
é um reescritor de URL que não serve o arquivo.
Com UseDefaultFiles
, as solicitações para uma pasta em wwwroot
procuram:
default.htm
default.html
index.htm
index.html
O primeiro arquivo encontrado na lista é servido como se a solicitação incluísse o nome do arquivo. O URL do navegador continua a refletir o URI solicitado.
O código a seguir altera o nome de 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 serviço de arquivos estáticos e o arquivo padrão. A navegação no diretório não está ativada:
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 serviço de arquivos estáticos, o arquivo padrão e a 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 serviço de arquivos estáticos, o arquivo padrão e a 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 deve ser chamado quando o valor da propriedade EnableDirectoryBrowsing
é true
.
Usando a hierarquia de arquivos e o código anteriores, 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 não existir nenhum arquivo com nome padrão no diretório MyStaticFiles
UseDefaultFiles e UseDirectoryBrowser efetuam um redirecionamento do lado do cliente do URI de destino sem um /
final para o URI de destino com um /
final. Por exemplo, de https://<hostname>/StaticFiles
para https://<hostname>/StaticFiles/
. URLs relativos dentro do diretório StaticFiles
FileExtensionContentTypeProvider
A classe FileExtensionContentTypeProvider contém uma propriedade Mappings
que serve como um mapeamento de extensões de arquivo para tipos de conteúdo MIME. No exemplo 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 Static File Middleware 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 passará a solicitação para o próximo middleware no pipeline. Se nenhum middleware lidar com a solicitação, uma resposta 404 Not Found será retornada. Se a navegação no diretório estiver habilitada, um link para o arquivo será exibido em uma listagem de diretório.
O código a seguir permite servir 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.
Advertência
Ativar ServeUnknownFileTypes é um risco de segurança. Ele está desativado por padrão, e seu uso é desencorajado. FileExtensionContentTypeProvider fornece uma alternativa mais segura ao serviço de arquivos com extensões não padrão.
Sirva arquivos de vários locais
Considere a seguinte página de 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 servir arquivos de outros locais. O exemplo a seguir chama UseStaticFiles
duas vezes para servir 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 Tag de Imagem AppendVersion não são aplicados porque os Auxiliares de Tag dependem de WebRootFileProvider.
WebRootFileProvider
não foi atualizado para incluir a pastaMyStaticFiles
.
O código a seguir atualiza o WebRootFileProvider
, que permite que o Image Tag Helper 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 aplica-se a Razor Pages e aplicativos MVC. Para obter orientações que se aplicam a Blazor Web Apps, consulte ASP.NET Core Blazor arquivos estáticos.
Considerações de segurança para arquivos estáticos
Advertência
UseDirectoryBrowser
e UseStaticFiles
podem vazar segredos. Desativar a navegação no diretório em produção é altamente recomendado. Analise cuidadosamente quais diretórios estão habilitados via UseStaticFiles
ou UseDirectoryBrowser
. Todo o diretório e seus subdiretórios tornam-se acessíveis ao público. Armazene arquivos adequados para servir ao público em um diretório dedicado, como <content_root>/wwwroot
. Separe esses arquivos de visualizações MVC, Razor Pages, arquivos de configuração, etc.
Os URLs para conteúdo exposto com
UseDirectoryBrowser
eUseStaticFiles
estão sujeitos às restrições de diferenciação de maiúsculas e minúsculas e caracteres do sistema de arquivos subjacente. Por exemplo, o Windows não diferencia maiúsculas de minúsculas, mas o macOS e o Linux não.ASP.NET aplicativos principais hospedados no IIS usam o do módulo principal do
ASP.NET para encaminhar todas as solicitações para o aplicativo, incluindo solicitações de arquivos estáticos. O manipulador de arquivos estáticos do IIS não é usado e não tem chance de lidar com solicitações. Conclua as seguintes etapas no Gerenciador do IIS para remover o manipulador de arquivos estáticos do IIS no nível do servidor ou do site:
- Navegue até ao recurso Módulos.
- Selecione StaticFileModule na lista.
- Clique
Remover na barra lateral Ações.
Advertência
Se o manipulador de arquivos estáticos do IIS estiver habilitado e o módulo principal do ASP.NET estiver configurado incorretamente, os arquivos estáticos serão servidos. Isso acontece, por exemplo, se o arquivo web.config não for implantado.
- Coloque os arquivos de código, incluindo
.cs
e.cshtml
, fora do diretório raiz do projeto de aplicação. 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 evita que o código do lado do servidor seja vazado.
Servir arquivos fora do wwwroot atualizando IWebHostEnvironment.WebRootPath
Quando IWebHostEnvironment.WebRootPath estiver definido para uma pasta diferente de wwwroot
:
- No ambiente de desenvolvimento, os ativos estáticos encontrados no
wwwroot
e noIWebHostEnvironment.WebRootPath
atualizado são servidos a partir dewwwroot
. - Em qualquer ambiente que não seja de desenvolvimento, recursos estáticos duplicados são servidos a partir da pasta
IWebHostEnvironment.WebRootPath
atualizada.
Considere um aplicativo Web criado com o modelo da Web vazio:
Contendo um ficheiro
Index.html
emwwwroot
ewwwroot-custom
.Com o seguinte arquivo de
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, os pedidos são feitos para /
:
- No ambiente de desenvolvimento retornar
wwwroot/Index.html
- Em qualquer ambiente que não seja o desenvolvimento, devolva
wwwroot-custom/Index.html
.
Para garantir que os ativos de wwwroot-custom
sejam devolvidos, use uma das seguintes abordagens:
Exclua ativos nomeados duplicados no
wwwroot
.Defina
"ASPNETCORE_ENVIRONMENT"
emProperties/launchSettings.json
para qualquer valor diferente de"Development"
.Desative completamente os ativos da Web estáticos definindo
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
no arquivo de projeto. AVISO, desativar os ativos estáticos da Web desabilita Razor Bibliotecas de Classes.Adicione o seguinte JSON ao arquivo de projeto:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
O código seguinte atualiza IWebHostEnvironment.WebRootPath
para um valor não associado ao desenvolvimento, assegurando que o conteúdo duplicado seja retornado de wwwroot-custom
em vez 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 serve diretamente aos clientes por padrão.
Servir arquivos estáticos
Os arquivos estáticos são armazenados dentro do diretório raiz da 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 a raiz de conteúdo e a raiz da Web .
O método CreateBuilder define a raiz do conteúdo para 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 através de um caminho relativo à raiz da Web . Por exemplo, os modelos de projeto Aplicativo Web contêm várias pastas dentro da pasta wwwroot
:
wwwroot
css
js
lib
Considere criar o pasta wwwroot/images e adicionar o arquivo wwwroot/images/MyImage.jpg
. O formato URI para acessar um arquivo na pasta images
é https://<hostname>/images/<image_file_name>
. Por exemplo, https://localhost:5001/images/MyImage.jpg
Servir ficheiros no diretório raiz da web
Os modelos de aplicativo Web padrão chamam o método UseStaticFiles no Program.cs
, que permite que arquivos estáticos sejam servidos:
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 sem parâmetros UseStaticFiles
marca os arquivos na raiz web como serventes. As marcações seguintes referem-se a wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Na marcação anterior, o caractere til ~
aponta para o diretório raiz da web .
Servir arquivos fora da raiz da web
Considere uma hierarquia de diretórios na qual os arquivos estáticos a serem servidos residem fora da raiz da 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 StaticFiles URI. Um pedido de https://<hostname>/StaticFiles/images/red-rose.jpg
serve o ficheiro red-rose.jpg
.
As seguintes referências ao marcador MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Para servir ficheiros a partir de várias localizações, consulte Servir ficheiros a partir de várias localizações.
Definir cabeçalhos de resposta HTTP
Um objeto StaticFileOptions pode ser usado para definir cabeçalhos de resposta HTTP. Além de configurar a disponibilização de arquivos estáticos a partir da raiz da Web , o código a seguir define o cabeçalho Cache-Control:
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 torna os arquivos estáticos publicamente disponíveis no cache local por uma semana (604800 segundos).
Autorização de arquivo estático
Os modelos ASP.NET Core chamam UseStaticFiles antes de chamar UseAuthorization. A maioria das aplicações segue este padrão. Quando o middleware de ficheiro estático é chamado antes do middleware de autorização:
- Nenhuma verificação de autorização é executada nos arquivos estáticos.
- Os arquivos estáticos servidos pelo Static File Middleware, como aqueles em
wwwroot
, são acessíveis publicamente.
Para servir 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 alternativa.
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 utilizadores sejam autenticados. Pontos de extremidade, como controladores, Razor Pages, etc., que especificam seus próprios requisitos de autorização não usam a política de autorização de fallback. Por exemplo, Razor Pages, 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 recurso.
RequireAuthenticatedUser adiciona DenyAnonymousAuthorizationRequirement à instância atual, o que impõe que o usuário atual seja autenticado.
Os ativos estáticos sob wwwroot
são publicamente acessíveis porque o Middleware de Arquivo Estático padrão (app.UseStaticFiles();
) é chamado antes de UseAuthentication
. Os ativos estáticos na pasta
Uma abordagem alternativa para servir ficheiros com base na autorização é:
- Armazene-os fora do
wwwroot
e de qualquer diretório acessível ao Static File Middleware. - Sirva-os através de um método de ação ao qual a autorização é aplicada e devolva 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");
}
}
Navegação no diretório
A navegação no diretório permite a listagem de diretórios dentro de diretórios especificados.
A navegação no diretório é desativada por padrão por motivos de segurança. Para obter mais informações, consulte Considerações de segurança para 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 do pasta wwwroot/images usando o URL https://<hostname>/MyImages
, com links para cada arquivo e pasta:
AddDirectoryBrowser
adiciona serviços exigidos pelo middleware de navegação no diretório, incluindo HtmlEncoder. Esses serviços podem ser adicionados por outras chamadas, como AddRazorPages, mas recomendamos ligar para AddDirectoryBrowser
para garantir que os serviços sejam adicionados em todos os aplicativos.
Servir documentos padrão
Definir uma página padrão fornece aos visitantes um ponto de partida em um site. Para servir um arquivo padrão do wwwroot
sem exigir que a URL da solicitação inclua 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 UseStaticFiles
para servir o arquivo padrão.
UseDefaultFiles
é um reescritor de URL que não serve o arquivo.
Com UseDefaultFiles
, as solicitações para uma pasta em wwwroot
pesquisam por:
default.htm
default.html
index.htm
index.html
O primeiro arquivo encontrado na lista é servido como se a solicitação incluísse o nome do arquivo. O URL do navegador continua a refletir o URI solicitado.
O código a seguir altera o nome de 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 serviço de arquivos estáticos e o arquivo padrão. A navegação no diretório não está ativada:
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 serviço de arquivos estáticos, o arquivo padrão e a 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 serviço de arquivos estáticos, o arquivo padrão e a 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 deve ser chamado quando o valor da propriedade EnableDirectoryBrowsing
é true
.
Usando a hierarquia de arquivos e o código anteriores, 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 não existir nenhum arquivo com nome padrão no diretório MyStaticFiles
UseDefaultFiles e UseDirectoryBrowser efetuam um redirecionamento no lado do cliente do URI de destino sem um /
para o URI de destino com um /
à direita. Por exemplo, de https://<hostname>/StaticFiles
para https://<hostname>/StaticFiles/
. URLs relativos no diretório StaticFiles são inválidos sem uma barra final (/
), a menos que a opção RedirectToAppendTrailingSlash de DefaultFilesOptions seja usada.
FileExtensionContentTypeProvider (ProvedorDeTipoDeConteúdoDeExtensãoDeFicheiro)
A classe FileExtensionContentTypeProvider contém uma propriedade Mappings
que serve como um mapeamento de extensões de arquivo para tipos de conteúdo MIME. No exemplo 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 Static File Middleware 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 passará a solicitação para o próximo middleware no pipeline. Se nenhum middleware lidar com a solicitação, uma resposta 404 Not Found será retornada. Se a navegação no diretório estiver habilitada, um link para o arquivo será exibido em uma listagem de diretório.
O código a seguir permite servir 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.
Advertência
Ativar ServeUnknownFileTypes é um risco de segurança. Ele está desativado por padrão, e seu uso é desencorajado. FileExtensionContentTypeProvider fornece uma alternativa mais segura ao serviço de arquivos com extensões não padrão.
Sirva arquivos de vários locais
Considere a seguinte página de 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
estão por defeito no provedor de arquivos que apontam para wwwroot
. Instâncias adicionais de UseStaticFiles
e UseFileServer
podem ser fornecidas com outros provedores de arquivos para servir arquivos de outros locais. O exemplo a seguir chama UseStaticFiles
duas vezes para servir 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 Tag de Imagem AppendVersion não são aplicados porque os Auxiliares de Tag dependem de WebRootFileProvider.
WebRootFileProvider
não foi atualizado para incluir a pastaMyStaticFiles
.
O código a seguir atualiza o WebRootFileProvider
, que permite que o Image Tag Helper 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
Advertência
UseDirectoryBrowser
e UseStaticFiles
podem vazar segredos. Desativar a navegação no diretório em produção é altamente recomendado. Analise cuidadosamente quais diretórios estão habilitados via UseStaticFiles
ou UseDirectoryBrowser
. Todo o diretório e seus subdiretórios tornam-se acessíveis ao público. Armazene arquivos adequados para servir ao público em um diretório dedicado, como <content_root>/wwwroot
. Separe esses arquivos de visualizações MVC, Razor Pages, arquivos de configuração, etc.
Os URLs para conteúdo exposto com
UseDirectoryBrowser
eUseStaticFiles
estão sujeitos às restrições de diferenciação de maiúsculas e minúsculas e caracteres do sistema de arquivos subjacente. Por exemplo, o Windows não diferencia maiúsculas de minúsculas, mas o macOS e o Linux não.ASP.NET aplicativos principais hospedados no IIS usam o do módulo principal do
ASP.NET para encaminhar todas as solicitações para o aplicativo, incluindo solicitações de arquivos estáticos. O manipulador de arquivos estáticos do IIS não é usado e não tem chance de lidar com solicitações. Conclua as seguintes etapas no Gerenciador do IIS para remover o manipulador de arquivos estáticos do IIS no nível do servidor ou do site:
- Navegue até a funcionalidade Módulos.
- Selecione StaticFileModule na lista.
- Clique
Remover na barra lateral Ações.
Advertência
Se o manipulador de arquivos estáticos do IIS estiver habilitado e o módulo principal do ASP.NET estiver configurado incorretamente, os arquivos estáticos serão servidos. Isso acontece, por exemplo, se o arquivo web.config não for implantado.
- Coloque arquivos de código, incluindo
e , fora da raiz web do projeto de aplicação . 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 evita que o código do lado do servidor seja vazado.
Servir arquivos fora do wwwroot atualizando IWebHostEnvironment.WebRootPath
Quando IWebHostEnvironment.WebRootPath estiver definido para uma pasta diferente de wwwroot
:
- No ambiente de desenvolvimento, os ativos estáticos encontrados no
wwwroot
e noIWebHostEnvironment.WebRootPath
atualizado são servidos a partir dewwwroot
. - Em qualquer ambiente que não seja de desenvolvimento, ativos estáticos duplicados são servidos a partir da pasta
IWebHostEnvironment.WebRootPath
atualizada.
Considere um aplicativo Web criado com o modelo da Web vazio:
Contendo um ficheiro
Index.html
nowwwroot
ewwwroot-custom
.Com o seguinte arquivo de
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, as requisições para /
:
- No ambiente de desenvolvimento, retornar o
wwwroot/Index.html
- Em qualquer ambiente que não seja o de desenvolvimento, retorna
wwwroot-custom/Index.html
Para garantir que os ativos de wwwroot-custom
sejam devolvidos, use uma das seguintes abordagens:
Exclua ativos nomeados duplicados no
wwwroot
.Defina
"ASPNETCORE_ENVIRONMENT"
emProperties/launchSettings.json
para qualquer valor diferente de"Development"
.Desative completamente os ativos da Web estáticos definindo
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
no arquivo de projeto. AVISO, desativar ativos da Web estáticos desabilita Razor Bibliotecas de Classe.Adicione o seguinte JSON ao arquivo de projeto:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
O seguinte código atualiza IWebHostEnvironment.WebRootPath
para um valor que não seja de desenvolvimento, garantindo que o conteúdo duplicado seja retornado do wwwroot-custom
em vez 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 serve diretamente aos clientes por padrão.
Visualizar ou descarregar código de exemplo (como descarregar)
Servir arquivos estáticos
Os arquivos estáticos são armazenados dentro do diretório raiz da 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 para 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 através de um caminho relativo ao raiz da web. Por exemplo, os modelos de projeto Aplicativo Web contêm várias pastas dentro da pasta wwwroot
:
wwwroot
css
js
lib
Considere criar o pasta wwwroot/images e adicionar o arquivo wwwroot/images/MyImage.jpg
. O formato URI para acessar um arquivo na pasta images
é https://<hostname>/images/<image_file_name>
. Por exemplo, https://localhost:5001/images/MyImage.jpg
Servir arquivos no diretório raiz da Web
Os modelos de aplicativo Web padrão chamam o método UseStaticFiles no Startup.Configure
, que permite que arquivos estáticos sejam servidos:
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 de método UseStaticFiles
sem parâmetros marca os arquivos em raiz da Web como serví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 da Web .
Servir arquivos fora da raiz da web
Considere uma hierarquia de diretórios na qual os arquivos estáticos a serem servidos residem fora da raiz da 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 em MyStaticFiles é exposta publicamente através do segmento de URI StaticFiles. Um pedido de https://<hostname>/StaticFiles/images/red-rose.jpg
serve o ficheiro red-rose.jpg
.
As seguintes marcações referem-se a 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 serviço de arquivo estático a partir doraiz da Web
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 ASP.NET Core chamam UseStaticFiles antes de chamar UseAuthorization. A maioria das aplicações segue este padrão. Quando o Middleware de Ficheiro Estático é chamado antes do Middleware de Autorização:
- Nenhuma verificação de autorização é executada nos arquivos estáticos.
- Os arquivos estáticos servidos pelo Static File Middleware, como aqueles em
wwwroot
, são acessíveis publicamente.
Para servir 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 alternativa .
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 todos os usuários sejam autenticados. Pontos de extremidade, como controladores, Razor Pages, etc., que especificam os seus próprios requisitos de autorização não usam a política de autorização de fallback. Por exemplo, Razor Pages, controladores ou métodos de ação com [AllowAnonymous]
ou [Authorize(PolicyName="MyPolicy")]
usam o atributo de autorização aplicado em vez de a política de autorização substituta.
RequireAuthenticatedUser adiciona DenyAnonymousAuthorizationRequirement à instância atual, o que impõe que o usuário atual seja autenticado.
Os ativos estáticos sob wwwroot
são acessíveis publicamente porque o Middleware de Arquivo Estático padrão (app.UseStaticFiles();
) é chamado antes do UseAuthentication
. Os ativos estáticos na pasta
Uma abordagem alternativa para servir ficheiros com base na autorização é:
- Armazene-os fora do
wwwroot
e de qualquer diretório acessível ao Static File Middleware. - Servi-los através de um método de ação ao qual é aplicada autorização 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");
}
Navegação no diretório
A navegação no diretório permite a listagem de diretórios dentro de diretórios especificados.
A navegação no diretório é desativada por padrão por motivos de segurança. Para obter mais informações, consulte Considerações de segurança para 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 do pasta wwwroot/images usando o URL https://<hostname>/MyImages
, com links para cada arquivo e pasta:
Servir documentos padrão
Definir uma página padrão fornece aos visitantes um ponto de partida em um site. Para servir um arquivo padrão do wwwroot
sem exigir que a URL da solicitação inclua 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 UseStaticFiles
para servir o arquivo padrão.
UseDefaultFiles
é um reescritor de URL que não serve o arquivo.
Com UseDefaultFiles
, solicitações para uma pasta em wwwroot
pesquisam:
default.htm
default.html
index.htm
index.html
O primeiro arquivo encontrado na lista é servido como se a solicitação incluísse o nome do arquivo. O URL do navegador continua a refletir o URI solicitado.
O código a seguir altera o nome de 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 seguinte mostra Startup.Configure
junto com o código precedente:
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 serviço de arquivos estáticos e o arquivo padrão. A navegação no diretório não está ativada. 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 serviço de arquivos estáticos, o arquivo padrão e a navegação no diretório:
app.UseFileServer(enableDirectoryBrowsing: true);
O código a seguir mostra Startup.Configure
com o código que o precede.
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 serviço de arquivos estáticos, o arquivo padrão e a 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 deve ser chamado quando o valor da propriedade EnableDirectoryBrowsing
é true
.
Usando a hierarquia de arquivos e o 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 não existir nenhum arquivo com nome padrão no diretório MyStaticFiles
UseDefaultFiles e UseDirectoryBrowser realizam um redirecionamento no lado do cliente do URI de destino sem um /
final para o URI de destino com um /
final. Por exemplo, de https://<hostname>/StaticFiles
para https://<hostname>/StaticFiles/
. As URLs relativas dentro do diretório StaticFiles são inválidas sem a barra final (/
).
FileExtensionContentTypeProvider
A classe FileExtensionContentTypeProvider contém uma propriedade Mappings
que serve como um mapeamento de extensões de arquivo para tipos de conteúdo MIME. No exemplo 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 seguinte código mostra Startup.Configure
com o código que o precede:
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 Static File Middleware 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 passará a solicitação para o próximo middleware no pipeline. Se nenhum middleware puder lidar com a solicitação, será retornada uma resposta 404 Not Found. Se a navegação no diretório estiver habilitada, um link para o arquivo será exibido em uma listagem de diretório.
O código a seguir permite servir 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.
Advertência
Ativar ServeUnknownFileTypes é um risco de segurança. Ele está desativado por padrão, e seu uso é desencorajado. FileExtensionContentTypeProvider fornece uma alternativa mais segura ao serviço de arquivos com extensões não padrão.
Sirva arquivos de vários locais
UseStaticFiles
e UseFileServer
são definidos por padrão para o provedor de arquivos apontar para wwwroot
. Instâncias adicionais de UseStaticFiles
e UseFileServer
podem ser fornecidas com outros provedores de arquivos para servir arquivos de outros locais. Para obter mais informações, consulte este problema do GitHub.
Considerações de segurança para arquivos estáticos
Advertência
UseDirectoryBrowser
e UseStaticFiles
podem vazar segredos. Desativar a navegação no diretório em produção é altamente recomendado. Analise cuidadosamente quais diretórios estão habilitados via UseStaticFiles
ou UseDirectoryBrowser
. Todo o diretório e seus subdiretórios tornam-se acessíveis ao público. Armazene arquivos adequados para servir ao público em um diretório dedicado, como <content_root>/wwwroot
. Separe esses arquivos de visualizações MVC, Razor Pages, arquivos de configuração, etc.
Os URLs para conteúdo exposto com
UseDirectoryBrowser
eUseStaticFiles
estão sujeitos às restrições de diferenciação de maiúsculas e minúsculas e caracteres do sistema de arquivos subjacente. Por exemplo, o Windows não diferencia maiúsculas de minúsculas, mas o macOS e o Linux não.ASP.NET aplicativos principais hospedados no IIS usam o do módulo principal do
ASP.NET para encaminhar todas as solicitações para o aplicativo, incluindo solicitações de arquivos estáticos. O manipulador de arquivos estáticos do IIS não é usado e não tem chance de lidar com solicitações. Conclua as seguintes etapas no Gerenciador do IIS para remover o manipulador de arquivos estáticos do IIS no nível do servidor ou do site:
- Navegue até o recurso Módulos.
- Selecione StaticFileModule na lista.
- Clique em Remover na barra lateral de Ações.
Advertência
Se o manipulador de arquivos estáticos do IIS estiver habilitado e o módulo principal do ASP.NET estiver configurado incorretamente, os arquivos estáticos serão servidos. Isso acontece, por exemplo, se o arquivo web.config não for implantado.
- Coloque arquivos de código, incluindo
.cs
e.cshtml
, fora da raiz da 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 evita que o código do lado do servidor seja vazado.