Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
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.
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.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Os arquivos estáticos são acessíveis através de um caminho relativo à raiz webdo 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 na raiz do servidor 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 como serváveis os arquivos na raiz da Web. 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 carácter 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 por meio do segmento URI StaticFiles. Um pedido de https://<hostname>/StaticFiles/images/red-rose.jpg
serve o ficheiro red-rose.jpg
.
As marcações seguintes referem-se 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();
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 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 Páginas, 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 substituiçã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 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");
// 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 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();
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 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 |
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 /
para o URI de destino com um /
. Por exemplo, de https://<hostname>/StaticFiles
para https://<hostname>/StaticFiles/
. URLs relativos dentro do diretório StaticFiles são inválidos sem uma barra final (/
), a menos que a opção RedirectToAppendTrailingSlash de DefaultFilesOptions seja usada.
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 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();
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
são configurados por padrão para o provedor de arquivos que aponta 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.Aplicações ASP.NET Core hospedadas no IIS usam o Módulo ASP.NET Core para encaminhar todas as solicitações para a aplicação, 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.UseStaticFiles(); 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 de desenvolvimento, 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 JSON 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.UseStaticFiles();
app.Run();
Recursos adicionais
- Ver ou baixar código de exemplo (como baixar)
- Middleware
- Introdução ao ASP.NET Core
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 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.UseStaticFiles();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
Os arquivos estáticos são acessíveis através de um caminho relativo à raiz webdo 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 na 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 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(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 URI StaticFiles. Um pedido de https://<hostname>/StaticFiles/images/red-rose.jpg
serve o ficheiro red-rose.jpg
.
As marcações seguintes referem-se 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();
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 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 Páginas, 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 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 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");
}
}
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 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();
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 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 |
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 /
para o URI de destino com um /
. Por exemplo, de https://<hostname>/StaticFiles
para https://<hostname>/StaticFiles/
. URLs relativas dentro do diretório StaticFiles são inválidas sem uma barra à direita (/
) a menos que a opção RedirectToAppendTrailingSlash de DefaultFilesOptions seja usada.
FileExtensionContentTypeProvider
A classe FileExtensionContentTypeProvider contém uma propriedade Mappings
que 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 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();
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
têm como padrão o provedor de arquivos que aponta 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.Aplicações ASP.NET Core hospedadas no IIS usam o módulo do ASP.NET Core para encaminhar todas as solicitações para a aplicação, 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.UseStaticFiles(); app.Run();
No código anterior, as requisições para /
:
- No ambiente de desenvolvimento, retorne
wwwroot/Index.html
- Em qualquer ambiente que não seja o ambiente de 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 JSON 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.UseStaticFiles();
app.Run();
Recursos adicionais
- Ver ou baixar código de exemplo (como baixar)
- Middleware
- Introdução ao ASP.NET Core
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.
Ver ou baixar código de exemplo (como baixar)
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 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 à raiz webdo 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 na raiz do servidor 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 do método UseStaticFiles
sem parâmetros marca os ficheiros na raiz da Web como disponíveis para serviço. As marcações seguintes referem-se a 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 MyStaticFiles é exposta publicamente por meio do segmento URI StaticFiles. Um pedido para https://<hostname>/StaticFiles/images/red-rose.jpg
entrega o ficheiro red-rose.jpg
.
As marcações seguintes 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 arquivos estáticos a partir da raiz da Web, o código a seguir define o cabeçalho Cache-Control
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
const string cacheMaxAge = "604800";
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
// using Microsoft.AspNetCore.Http;
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAge}");
}
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
O código anterior define a idade máxima como 604800 segundos (7 dias).
Autorização de arquivo estático
Os modelos 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 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 em autorização:
- Armazene-os fora de
wwwroot
. - Chame
UseStaticFiles
, especificando um caminho, depois de chamarUseAuthorization
. - Defina a política de autorização de fallback.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
// wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
}
// Remaining code ommitted for brevity.
No código anterior, a política de autorização de fallback exige 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 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 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:
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
, 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 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 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();
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 EnableDirectoryBrowsing
da propriedade é 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 /
para o URI de destino com um /
. 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 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();
// 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 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:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
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();
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 ficheiros que aponta 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.Aplicações ASP.NET Core hospedadas no IIS usam o Módulo ASP.NET Core para encaminhar todas as solicitações para a aplicação, 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.