Configurando o middleware de StaticFiles com .NET 6
Recentemente me deparei com um projeto que precisava entregar alguns arquivos estáticos (css, js e imagens fora do diretório padrão do projeto wwwroot). Pesquisando encontrei algumas maneiras e como podemos configurar o middlware de StaticFiles no .NET 6.
Por isso decidir escrever este post com algumas das possibilidades de configuração que temos no middleware de StaticFiles.
Padrão do StaticFiles
Uma coisa interessante das novas verões do ASP.NET é a de ser possível compor a aplicação com os recursos necessários, por exemplo, caso você esteja criando uma API, provavelmente não é necessário "pagar" o custo de gerenciar arquivos estáticos em sua aplicação. Por padrão, para utilizarmos eles é necessário plugar um middleware no pipeline de nossa aplicação.
Com isso podemos criar ou utilizar a pasta padrão wwwroot e nela entregarmos os arquivos estáticos:
Entregando arquivos fora do wwwroot
Podemos configurar o middleware de Static Files para outro cenário, em um cenário que precisemos entregar arquivos estáticos que estão em outra hierarquia de pastas no projeto que não no wwwroot.
Lembrando que isto deixa a aplicação fora do padrão, mas também é uma possibilidade. Neste exemplo criei um diretório chamado MinhasImagens na raiz da aplicação web.
Para esta opção funcionar precisamos configurar o middleware de Static Files da seguinte maneira:
E nas views com Razor podemos chamar a imagem diretamente:
<img src="~/img1.png" alt="Minha Imagem" />
Desta maneira tanto meus arquivos no wwwroot quanto na pasta nova estarão acessíveis:
Existe outra opção que podemos configurar, a RequestPath também, nesta nossos arquivos serão servidos com um diretório padrão configurado nas URLs que entregarão eles:
Com isso em nossas Views teremos que chamar os recursos dentro do diretório da seguinte maneira:
<img src="~/estaticos/img1.png" alt="Minha Imagem" />
Utilizando desta maneira podemos separar e ter uma independência dos dois diretórios utilizados na aplicação: wwwroot e o MinhasImagens.
Configurando cache HTTP com response headers
Uma das coisas que mais ajudam no desempenho das aplicações web são as configurações de Cache no navegador do cliente, isto impede que durante a navegação a pessoa precise baixar novamente aquele recurso, evitando todo o custo de uma requisição para o servidor, banda, latência, etc.
No .NET podemos configurar para o Middleware de Static Files incluir um header na resposta, esta header para o cache se chama Cache-Control:
Importante sempre utilizamos o tag helper de Append Version quando referenciarmos os arquivos (isto evita que o cliente tenha que limpar o cache do navegador).
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
Agora temos os arquivos estáticos com o header de cache configurado:
Listagem de diretório
Mesmo sendo um problema critico de segurança, em alguns cenários pode ser necessário listar todos os arquivos de um diretório de nossa aplicação, utilize esta feature com muito cuidado.
Para listar os arquivos podemos configurar o Middleware de Static Files da seguinte maneira, lembrando ser necessário adicionar a injeção de dependência do DirectoryBrowser.
Feito isso, nosso diretório estará disponível nas aplicações:
Entregando arquivos padrões com o Default Documents
Caso estejamos utilizando arquivos padrões como index.html, index.htm, default.html e default.htm em nossos diretórios de arquivos estáticos, podemos utilizar o Middleware de DefaultFiles antes de nosso middleware de Static Files no configuração do pipeline da nossa aplicação:
Ainda neste middleware é possivel configurar qual documento padrão deverá ser procurado ao acessar aquele diretório:
Mapeando extensões com o FileExtensionContentTypeProvider
Outra configuração que podemos utilizar no Static Files é feita através do FileExtesionContentTypeProvider, ele possui um mapeamento das extensões e MIME content types, neste exemplo configurei duas extensões novas, aterei o MIME type de outra e removi a entrega de .mp4 da nossa aplicação:
Utilizando tipos que não são padrões com o Non-standard content types
Outra possibilidade que traz um certo risco para nossa aplicação é a de entregar aquivos com extensões que não são conhecidas, por padrão o ASP.NET tem quase 400 tipos mapeados. Caso seja necessário entregar aquivos não conhecidos e que não conseguimos mapear no exemplo acima é possível configurar o Middleware de Static Files da seguinte maneira:
Com isto arquivos não conhecidos serão entregues e renderizados como imagem.
Utilizando autenticação para entrega de arquivos estáticos
Por fim, uma configuração que pode ser útil é a de exigir autenticação para consumir arquivos de um diretório específico de nossa aplicação.
Para isto devemos hospedar eles como no exemplo acima (fora do wwwroot que é publico), e devemos chamar o UseStaticFiles novamente após o UseAuthorization no pipeline da nossa aplicação.
Ficamos com a seguinte configuração:
Lembrando que arquivos estáticos que os clientes fazem upload em nossas aplicações sempre devem ser armazenados fora dela (ex: Blob, S3, etc) sempre pensando que podemos escalar horizontalmente nossas aplicações e que elas irão morrer e serem recriadas.
Bom espero que este post seja útil, estou a disposição para dúvidas, críticas e sugestões
abs
Rodolfo