Archivos estáticos en ASP.NET Core

Note

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión de .NET 10 de este artículo.

Warning

Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la directiva de compatibilidad de .NET y .NET Core. Para la versión actual, consulte la versión de .NET 10 de este artículo.

Los archivos estáticos, también denominados activos estáticos, son archivos de una aplicación de ASP.NET Core que no se generan dinámicamente. En su lugar, la aplicación los sirve directamente a los clientes cuando los solicitan. Algunos ejemplos de archivos estáticos incluyen archivos HTML, CSS, imagen y JavaScript.

Para obtener Blazor instrucciones acerca de archivos estáticos, que se suma o sustituye a las instrucciones de este artículo, consulte archivos estáticos de ASP.NET CoreBlazor.

Para habilitar el control de archivos estáticos en ASP.NET Core, llame a MapStaticAssets.

De forma predeterminada, almacene archivos estáticos en el directorio raíz web del proyecto. El directorio predeterminado es {CONTENT ROOT}/wwwroot, donde el {CONTENT ROOT} marcador de posición es la raíz de contenido de la aplicación. Solo los archivos de la wwwroot carpeta son direccionables, por lo que no es necesario preocuparse por el resto del código.

Solo los archivos con extensiones de archivo específicas asignadas a tipos multimedia admitidos se tratan como recursos web estáticos.

Los recursos web estáticos se detectan en tiempo de compilación y se optimizan mediante la huella digital basada en contenido para evitar la reutilización de archivos antiguos. Los recursos también se comprimen para reducir el tiempo de entrega de recursos.

En tiempo de ejecución, los recursos web estáticos detectados se exponen como puntos de conexión con encabezados HTTP aplicados, como encabezados de almacenamiento en caché y encabezados de tipo de contenido. Un recurso se sirve una vez hasta que el archivo cambia o el explorador borra su caché. Los encabezados ETag, Last-Modified y Content-Type están establecidos. El explorador no puede usar activos obsoletos después de actualizar una aplicación.

La entrega de recursos estáticos se basa en el enrutamiento de puntos de conexión, por lo que funciona con otras características compatibles con el punto de conexión, como la autorización. Está diseñado para trabajar con todos los marcos de interfaz de usuario, como Blazor, Razor Pages y MVC.

Mapear Activos Estáticos proporciona las siguientes ventajas:

  • Compresión en tiempo de compilación para todos los recursos de la aplicación, incluidos JavaScript (JS) y hojas de estilos, pero excluyendo los recursos de imagen y fuente que ya están comprimidos. La compresión Gzip (Content-Encoding: gz) se usa durante el desarrollo. La compresión Gzip y Brotli (Content-Encoding: br) se usan durante la publicación.
  • Generación de huellas digitales para todos los recursos en tiempo de compilación con una cadena codificada en Base64 del hash SHA-256 del contenido de cada archivo. Esto evita la reutilización de una versión anterior de un archivo, incluso si el archivo anterior está almacenado en caché. Los recursos con huellas digitales se almacenan en caché mediante la immutable directiva , lo que da como resultado que el explorador no vuelva a solicitar el recurso hasta que cambie. En el caso de los navegadores que no admiten la immutable directiva, se agrega una max-age directiva.
    • Incluso si un activo no está fingerprintado, se generará contenido basado en ETags para cada activo estático utilizando el hash de huella digital del archivo como valor ETag. Esto garantiza que el explorador solo descargue un archivo si su contenido cambia (o el archivo se descarga por primera vez).
    • Internamente, el marco asigna recursos físicos a sus huellas digitales, lo que permite a la aplicación:
      • Busque recursos generados automáticamente, como Razor el CSS con ámbito de componente para la función de aislamiento de CSS de Blazor y JS los recursos descritos por JS mapas de importación.
      • Genere etiquetas de vínculo en el <head> contenido de la página para precargar los recursos.

Map Static Assets no proporciona características para la minificación u otras transformaciones de archivos. La minificación normalmente se controla mediante código personalizado o herramientas de terceros.

Note

MapStaticAssets no proporciona documentos predeterminados por sí solos. Para proporcionar documentos predeterminados, llame a UseDefaultFiles seguido de UseStaticFiles. Para obtener más información, consulte la sección Servir documentos predeterminados .

Para habilitar el control de archivos estáticos en ASP.NET Core, llame a UseStaticFiles.

De forma predeterminada, almacene archivos estáticos en el directorio raíz web del proyecto. El directorio predeterminado es {CONTENT ROOT}/wwwroot, donde el {CONTENT ROOT} marcador de posición es la raíz de contenido de la aplicación. Solo los archivos de la wwwroot carpeta son direccionables, por lo que no es necesario preocuparse por el resto del código.

En tiempo de ejecución, el middleware de archivos estáticos devuelve los recursos web estáticos cuando se solicitan con los encabezados de modificación de recursos y de tipo de contenido aplicados. Los encabezados ETag, Last-Modified y Content-Type están establecidos.

El middleware de archivos estáticos habilita el servicio de archivos estáticos y una aplicación lo utiliza cuando UseStaticFiles se llama en la canalización de procesamiento de solicitudes de la aplicación. Los archivos se sirven desde la ruta de acceso especificada en IWebHostEnvironment.WebRootPath o WebRootFileProvider, que tiene como valor predeterminado la carpeta raíz web, normalmente wwwroot.

También puede servir recursos web estáticos desde proyectos y paquetes a los que se hace referencia.

Cambiar el directorio raíz web

Para cambiar la raíz web, use el UseWebRoot método . Para obtener más información, consulte visión general de los fundamentos de ASP.NET Core.

Evite la publicación de archivos en wwwroot con el elemento del proyecto <Content> del archivo de proyecto. En el ejemplo siguiente se impide la publicación de contenido en wwwroot/local y sus subdirectorios:

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

El método CreateBuilder establece la raíz de contenido en el directorio actual:

var builder = WebApplication.CreateBuilder(args);

El método CreateDefaultBuilder establece la raíz de contenido en el directorio actual:

Host.CreateDefaultBuilder(args)

En la canalización de procesamiento de solicitudes, después de la llamada a UseHttpsRedirection, llame MapStaticAssets a para habilitar el servicio de archivos estáticos desde la raíz web de la aplicación:

app.MapStaticAssets();

En la canalización de procesamiento de solicitudes, después de la llamada a UseHttpsRedirection, llame UseStaticFiles a para habilitar el servicio de archivos estáticos desde la raíz web de la aplicación:

app.UseStaticFiles();

Se puede acceder a los archivos estáticos a través de una ruta de acceso relativa a la raíz web.

Para acceder a una imagen en wwwroot/images/favicon.png:

  • Formato de dirección URL: https://{HOST}/images/{FILE NAME}
    • El {HOST} marcador de posición es el host.
    • El {FILE NAME} marcador de posición es el nombre de archivo.
  • Ejemplos
    • Dirección URL absoluta: https://localhost:5001/images/favicon.png
    • Dirección URL relativa raíz: images/favicon.png

En una Blazor aplicación, images/favicon.png carga la imagen de icono (favicon.png) desde la carpeta de wwwroot/images la aplicación:

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

En Razor Pages y las aplicaciones MVC, el carácter de tilde ~ apunta a la raíz web. En el ejemplo siguiente, ~/images/favicon.png carga la imagen de icono (favicon.png) desde la carpeta de wwwroot/images la aplicación:

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

Interrumpir la canalización de middleware

Para evitar ejecutar toda la canalización de middleware una vez que se ha coincidido un recurso estático, que es el comportamiento de UseStaticFiles, llame a ShortCircuit en MapStaticAssets. Llamar a ShortCircuit inmediatamente ejecuta el punto de conexión y devuelve la respuesta, impidiendo que otro middleware se ejecute para las solicitudes de recursos estáticos:

app.MapStaticAssets().ShortCircuit();

Control del almacenamiento en caché de archivos estáticos durante el desarrollo

Cuando se ejecuta en el Development entorno, por ejemplo, durante las pruebas de desarrollo de Visual Studio Recarga activa, el framework invalida los encabezados de caché para evitar que los navegadores almacenen archivos estáticos en caché. Este comportamiento ayuda a garantizar que la versión más reciente de los archivos se use cuando cambian los archivos, evitando problemas con el contenido obsoleto. En producción, el marco establece los encabezados de caché correctos, por lo que los exploradores pueden almacenar en caché los recursos estáticos según lo previsto.

Para deshabilitar este comportamiento, establezca EnableStaticAssetsDevelopmentCaching a true en el archivo de configuración de la aplicación del entorno Development (appsettings.Development.json).

Archivos estáticos en entornos diferentes a Development

Cuando se ejecuta una aplicación localmente, el Development entorno es el único entorno que habilita los recursos web estáticos. Para habilitar archivos estáticos para entornos distintos al Development durante el desarrollo local y las pruebas (por ejemplo, en el entorno Staging), llame a UseStaticWebAssets en el WebApplicationBuilder.

Warning

Llama a UseStaticWebAssets para el entorno exacto con el fin de evitar que se active la característica en producción, ya que sirve archivos desde ubicaciones separadas en el disco distintas de las del proyecto. Este ejemplo en esta sección verifica el entorno Staging con IsStaging.

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

Servir archivos fuera del directorio raíz web a través de IWebHostEnvironment.WebRootPath

Cuando se configura IWebHostEnvironment.WebRootPath en una carpeta distinta de wwwroot, la aplicación presenta los siguientes comportamientos predeterminados:

  • En el Development entorno, los recursos estáticos se sirven desde wwwroot si los recursos con el mismo nombre están en wwwroot y en una carpeta diferente asignada a WebRootPath.
  • En cualquier entorno distinto de Development, los recursos estáticos duplicados se sirven desde la WebRootPath carpeta .

Considere la posibilidad de crear una aplicación web a partir de la plantilla web vacía:

  • Que contenga un archivo Index.html en wwwroot y wwwroot-custom.
  • El Program archivo se actualiza para establecer WebRootPath = "wwwroot-custom".
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    WebRootPath = "wwwroot-custom"
});

De forma predeterminada, para las solicitudes a /:

  • En el Development entorno, wwwroot/Index.html se devuelve.
  • En cualquier entorno distinto de Development, wwwroot-custom/Index.html se devuelve .

Para asegurarse de que los recursos de wwwroot-custom siempre se devuelven, use uno de los métodos siguientes:

  • Elimine los recursos con nombre duplicado en wwwroot.

  • Establece ASPNETCORE_ENVIRONMENT en Properties/launchSettings.json a cualquier valor distinto de Development.

  • Deshabilite los recursos web estáticos estableciendo <StaticWebAssetsEnabled>false en en el archivo de proyecto de la aplicación. ADVERTENCIA: Al deshabilitar los recursos web estáticos, se Razor deshabilitan las bibliotecas de clases.

  • Agregue el siguiente CÓDIGO XML al archivo del proyecto:

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

El código siguiente actualiza WebRootPath a un valor que no es de desarrollo (Staging), garantizando que el contenido duplicado se devuelva desde wwwroot-custom en lugar de wwwroot.

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

Middleware de archivos estáticos

El middleware de archivos estáticos permite servir archivos estáticos en escenarios específicos, normalmente además de las convenciones de enrutamiento de puntos de conexión de Map Static Assets (MapStaticAssets).

El middleware de archivos estáticos se incluye en el procesamiento de solicitudes cuando se llama a UseStaticFiles en la canalización de procesamiento de solicitudes de la aplicación, normalmente después de añadir las convenciones de punto de conexión Map Static Assets (MapStaticAssets).

Las convenciones de punto de conexión Map Static Assets se utilizan en aplicaciones destinadas a .NET 9 o versiones posteriores. El middleware de archivos estáticos debe usarse en aplicaciones destinadas a versiones de .NET anteriores a .NET 9.

El middleware para archivos estáticos entrega archivos estáticos, pero no proporciona el mismo nivel de optimización que las convenciones de punto de conexión de Map Static Assets. Las funciones de compresión en tiempo de compilación y de generación de huellas digitales de las convenciones del punto de conexión Map Static Assets no están disponibles cuando solo se utiliza el middleware de archivos estáticos.

Las convenciones de punto de conexión están optimizadas para servir recursos de los que la aplicación tiene conocimiento en tiempo de ejecución. Si la aplicación sirve archivos desde otras ubicaciones, como el disco o recursos incrustados, use el middleware de archivos estáticos.

Las siguientes características descritas en este artículo son compatibles con el middleware de archivos estáticos, pero no con las convenciones de punto de conexión de Map Static Assets:

Servir archivos fuera del directorio raíz web a través de UseStaticFiles

Considere la siguiente jerarquía de directorios con archivos estáticos que residen fuera de la raíz web de la aplicación en una carpeta denominada ExtraStaticFiles:

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

Una solicitud puede acceder a red-rose.jpg configurando una nueva instancia de middleware de archivos estáticos:

Espacios de nombres para la API siguiente:

using Microsoft.Extensions.FileProviders;

En la canalización de procesamiento de solicitudes, después de la llamada existente a MapStaticAssets (.NET 9 o posterior) o UseStaticFiles (.NET 8 o versiones anteriores):

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

En el código anterior, la ExtraStaticFiles jerarquía de directorios se expone públicamente a través del static-files segmento de dirección URL. Una solicitud a https://{HOST}/StaticFiles/images/red-rose.jpg, donde el marcador de posición {HOST} es el host, sirve el archivo red-rose.jpg.

El siguiente marcado hace referencia a ExtraStaticFiles/images/red-rose.jpg:

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

En el ejemplo anterior, la notación tilde-slash se admite en Razor Pages y vistas MVC (src="~/StaticFiles/images/red-rose.jpg"), no para los componentes Razor en las aplicaciones Blazor.

Entrega de archivos desde varias ubicaciones

Las instrucciones de esta sección se aplican a Razor las aplicaciones Pages y MVC. Para obtener guías que se aplican a Blazor Web App, consulta Archivos estáticos Blazor de ASP.NET Core.

Tenga en cuenta el marcado siguiente que muestra un logotipo de la empresa:

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

El desarrollador pretende usar el asistente de etiquetas de imagen para anexar una versión y servir el archivo desde una ubicación personalizada, una carpeta denominada ExtraStaticFiles.

En el siguiente ejemplo, MapStaticAssets se utiliza para servir archivos desde wwwroot y UseStaticFiles se utiliza para servir archivos desde ExtraStaticFiles.

En la canalización de procesamiento de solicitudes, después de la llamada existente a MapStaticAssets (.NET 9 o posterior) o UseStaticFiles (.NET 8 o versiones anteriores):

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

En el ejemplo siguiente se llama UseStaticFiles dos veces para servir archivos desde wwwroot y ExtraStaticFiles.

En la canalización de procesamiento de solicitudes, después de la llamada existente a UseStaticFiles:

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

Con el código anterior, se muestra el ExtraStaticFiles/logo.png archivo. Sin embargo, el Image Tag Helper (AppendVersion) no se aplica porque depende de WebRootFileProvider, que no se ha actualizado para incluir la carpeta ExtraStaticFiles.

El siguiente código actualiza WebRootFileProvider para incluir la carpeta ExtraStaticFiles mediante un CompositeFileProvider. Esto permite al asistente de etiquetas de imagen aplicar una versión a las imágenes de la ExtraStaticFiles carpeta.

Espacio de nombres para la siguiente API:

using Microsoft.Extensions.FileProviders;

En la canalización de procesamiento de solicitudes antes de la llamada existente a MapStaticAssets (.NET 9 o posterior) o UseStaticFiles (.NET 8 o versiones anteriores):

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

var compositeProvider = new CompositeFileProvider(webRootProvider, newPathProvider);

app.Environment.WebRootFileProvider = compositeProvider;

UseStaticFiles y UseFileServer por defecto usan el proveedor de archivos que apunta a wwwroot. Se pueden proporcionar instancias adicionales de UseStaticFiles y UseFileServer con otros proveedores de archivos para proporcionar archivos desde otras ubicaciones. Para obtener más información, vea UseStaticFiles sigue siendo necesario con UseFileServer para wwwroot (dotnet/AspNetCore.Docs #15578).

Establecer encabezados de respuesta HTTP

Use StaticFileOptions para establecer encabezados de respuesta HTTP. Además de configurar el middleware de archivos estáticos para servir archivos estáticos, el siguiente código establece el encabezado Cache-Control en 604 800 segundos (una semana).

Espacios de nombres para la API siguiente:

using Microsoft.AspNetCore.Http;

En la canalización de procesamiento de solicitudes, después de la llamada existente a MapStaticAssets (.NET 9 o posterior) o UseStaticFiles (.NET 8 o versiones anteriores):

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

Gran colección de activos

Cuando se trabaja con grandes colecciones de recursos, que se consideran alrededor de 1000 o más recursos, se recomienda usar un agrupador para reducir el número final de recursos servidos por la aplicación o para combinar MapStaticAssets con UseStaticFiles.

MapStaticAssets Carga diligentemente los metadatos precomputados capturados durante el proceso de compilación para los recursos con el fin de admitir la compresión, el almacenamiento en caché y la huella digital. Estas características tienen el costo de un mayor uso de memoria por parte de la aplicación. En el caso de los recursos a los que se accede con frecuencia, normalmente vale la pena los costos. En el caso de los recursos a los que no se accede con frecuencia, es posible que la compensación no valga la pena.

Si no utiliza el empaquetado, le recomendamos combinar MapStaticAssets con UseStaticFiles. En el ejemplo siguiente se muestra el enfoque.

En el archivo de proyecto (.csproj), la propiedad de MSBuild StaticWebAssetEndpointExclusionPattern se usa para filtrar los endpoints del manifiesto final para MapStaticAssets. Los archivos excluidos son servidos por UseStaticFiles y no se benefician de la compresión, el almacenamiento en caché y la huella digital.

Al establecer el valor de StaticWebAssetEndpointExclusionPattern, conserve $(StaticWebAssetEndpointExclusionPattern) para mantener el patrón de exclusión predeterminado del marco de trabajo. Agregue patrones adicionales en una lista separada por punto y coma.

En el ejemplo siguiente, el patrón de exclusión excluye los archivos estáticos en la lib/icons carpeta, que representa un lote hipotético de iconos.

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

Tras el procesamiento del middleware de redireccionamiento HTTPS (app.UseHttpsRedirection();) en el archivo Program:

app.UseStaticFiles();

app.UseAuthorization();

app.MapStaticAssets();

Manifiesto de recursos estáticos

MapStaticAssets sirve recursos de un manifiesto de recursos estáticos en lugar de examinar la raíz web en tiempo de ejecución. El manifiesto se genera durante la compilación y la publicación, y registra los recursos web estáticos descubiertos para la aplicación, junto con metadatos como huellas de contenido, encabezados Content-Type, encabezados de caché y las representaciones comprimidas calculadas previamente (Gzip y Brotli). En tiempo de ejecución, MapStaticAssets lee el manifiesto, registra un punto de conexión para cada recurso y sirve las respuestas optimizadas.

El manifiesto se genera en el directorio de salida de compilación en tiempo de compilación. Su nombre de archivo se basa en el nombre del ensamblado del proyecto (por ejemplo, {ASSEMBLY NAME}.staticwebassets.endpoints.json, donde {ASSEMBLY NAME} es el marcador de posición del valor de MSBuild AssemblyName de la aplicación). Para proporcionar un manifiesto desde otra ubicación, consulte la sección Proporcionar un manifiesto de archivos estáticos personalizado .

Como MapStaticAssets solo sirve los recursos enumerados en el manifiesto, los archivos que no forman parte del manifiesto no se sirven por MapStaticAssets. Los archivos no forman parte del manifiesto cuando son:

  • Ubicado fuera de la raíz web en tiempo de compilación, como los archivos servidos desde el disco, los recursos incrustados o un conjunto personalizado WebRootPath en tiempo de ejecución.
  • Se excluye del manifiesto mediante la propiedad StaticWebAssetEndpointExclusionPattern de MSBuild (consulte la sección Gran colección de recursos).

Para proporcionar archivos que no están en el manifiesto, llame a UseStaticFiles, que sirve archivos directamente desde la raíz web en tiempo de ejecución. Esto también es por lo que servir documentos predeterminados con MapStaticAssets requiere una llamada a UseStaticFiles.

Autorización de archivos estáticos

Cuando una aplicación usa una directiva de autorización de respaldo, exige autorización en todas las solicitudes que no especifican explícitamente ninguna directiva de autorización. Este requisito incluye solicitudes de archivos estáticos después de que el middleware de autorización procese solicitudes. Para permitir el acceso anónimo a archivos estáticos, aplique AllowAnonymousAttribute al generador de puntos de conexión para archivos estáticos:

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

Cuando una aplicación adopta una directiva de autorización alternativa, se requiere autorización para todas las solicitudes que no especifican explícitamente una directiva de autorización, incluidas las solicitudes de archivos estáticos una vez que el middleware de autorización haya procesado las solicitudes. Las plantillas de ASP.NET Core permiten el acceso anónimo a archivos estáticos llamando a UseStaticFiles antes de llamar a UseAuthorization. La mayoría de las aplicaciones siguen este patrón. Cuando se ejecuta el middleware de archivos estáticos antes del middleware de autorización:

  • No se realizan comprobaciones de autorización en los archivos estáticos.
  • Los archivos estáticos servidos por el middleware de archivos estáticos, como los de la raíz web (normalmente, wwwroot), son accesibles públicamente.

Para proporcionar archivos estáticos según su autorización:

  • Confirme que la aplicación establece la directiva de autorización alternativa para requerir usuarios autenticados.
  • Almacene el archivo estático fuera de la raíz web de la aplicación.
  • Después de llamar a UseAuthorization, llame a UseStaticFilesy especifique la ruta de acceso a la carpeta de archivos estáticos fuera de la raíz web.

Espacios de nombres para la API siguiente:

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

Registro del servicio:

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

En la canalización de procesamiento de solicitudes después de la llamada a UseAuthorization:

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

Espacios de nombres para la API siguiente:

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

En Startup.ConfigureServices:

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

En Startup.Configure después de la llamada a UseAuthorization:

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

En el código anterior, la directiva de autorización de reserva requiere que se autentiquen los usuarios. Los puntos de conexión, como los controladores y Razor Pages, que especifican sus propios requisitos de autorización no usan la directiva de autorización de reserva. Por ejemplo, Razor Pages, controladores o métodos de acción con [AllowAnonymous] o [Authorize(PolicyName="MyPolicy")] usan el atributo de autorización aplicado en lugar de la directiva de autorización de reserva.

RequireAuthenticatedUser agrega DenyAnonymousAuthorizationRequirement a la instancia actual, lo que exige que el usuario actual se autentique.

Los recursos estáticos almacenados en la raíz web de la aplicación son accesibles públicamente porque se llama al middleware de archivos estáticos predeterminado (UseStaticFiles) antes de UseAuthorization. Los recursos estáticos de la SecureStaticFiles carpeta requieren autenticación.

Un enfoque alternativo para servir archivos según la autorización es:

  • Almacene los archivos fuera de la raíz web y de cualquier directorio al que pueda acceder el middleware de archivos estáticos.
  • Sirva los archivos a través de un método de acción al que se aplica la autorización y devuelva un FileResult objeto.

Desde una Razor página (Pages/BannerImage.cshtml.cs):

public class BannerImageModel : PageModel
{
    private readonly IWebHostEnvironment _env;

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

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

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

Desde un controlador (Controllers/HomeController.cs):

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

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

El enfoque anterior requiere una página o un punto de conexión por archivo.

En el siguiente ejemplo de punto final de ruta se devuelven archivos para usuarios autenticados.

En el archivo Program:

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

...

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

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

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

En el ejemplo de punto de conexión de ruta siguiente se cargan archivos para los usuarios autenticados en el rol de administrador (admin).

En el archivo Program:

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

...

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

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

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

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

En Startup.ConfigureServices:

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

En Startup.Configure:

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

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

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

El código siguiente carga archivos para los usuarios autenticados en el rol de administrador (admin).

En Startup.ConfigureServices:

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

En Startup.Configure:

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

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

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

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

Exploración de directorios

La exploración de directorios permite listar directorios en los directorios especificados.

Por motivos de seguridad, la exploración de directorios está deshabilitada de forma predeterminada. Para obtener más información, consulta Consideraciones de seguridad para archivos estáticos.

Habilite la exploración de directorios mediante las siguientes API:

En el ejemplo siguiente:

  • Una images carpeta en la raíz de la aplicación contiene imágenes para la exploración de directorios.
  • La ruta de solicitud para examinar las imágenes es /DirectoryImages.
  • Llamar a UseStaticFiles y establecer el FileProvider de StaticFileOptions permite mostrar enlaces del navegador a los archivos individuales.

Espacios de nombres para la API siguiente:

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

Registro del servicio:

builder.Services.AddDirectoryBrowser();

En la canalización de procesamiento de solicitudes, después de la llamada existente a MapStaticAssets (.NET 9 o posterior) o UseStaticFiles (.NET 8 o versiones anteriores):

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

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

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

Espacios de nombres para la API siguiente:

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

En Startup.ConfigureServices:

services.AddDirectoryBrowser();

En Startup.Configure, después de la llamada existente a UseStaticFiles:

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

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

El código anterior permite la exploración de directorios de la wwwroot/images carpeta mediante la dirección URL https://{HOST}/DirectoryImages con vínculos a cada archivo y carpeta, donde el {HOST} marcador de posición es el host.

AddDirectoryBrowser agrega servicios requeridos por el middleware de exploración de directorios, incluido HtmlEncoder. Estos servicios se pueden agregar mediante otras llamadas, como AddRazorPages, pero se recomienda llamar AddDirectoryBrowser para asegurarse de que se agregan los servicios.

Servir documentos predeterminados

El establecimiento de una página predeterminada proporciona a los visitantes un punto inicial en un sitio. Para proporcionar un archivo predeterminado desde wwwroot sin necesidad de que la URL de la solicitud incluya el nombre del archivo, llame al método UseDefaultFiles.

UseDefaultFiles es un sistema de reescritura de direcciones URL que no proporciona el archivo. Vuelve a escribir la dirección URL de la solicitud en el documento predeterminado (por ejemplo, / en /index.html) y otro componente sirve el archivo.

Dado que MapStaticAssets proporciona recursos detectados en tiempo de compilación a través del enrutamiento de puntos de conexión, no proporciona documentos predeterminados por sí mismos. Llame UseDefaultFiles a para volver a escribir la solicitud, seguida de UseStaticFiles para atender la solicitud reescrita del documento predeterminado:

app.UseDefaultFiles();
app.UseStaticFiles();
app.MapStaticAssets();

Importante

La configuración solo UseDefaultFiles y MapStaticAssets (sin UseStaticFiles) devuelve una respuesta 404: no encontrada para una solicitud a /. Esto se debe a que el alojamiento mínimo agrega el middleware de enrutamiento al principio de la canalización de procesamiento de solicitudes, por lo que el enrutamiento de puntos de conexión hace coincidir la solicitud antes de que UseDefaultFiles la reescriba en el documento predeterminado. El problema es especialmente evidente cuando se cambia la raíz web a una ruta de acceso personalizada con WebRootPath, porque los archivos de una raíz web personalizada no forman parte del manifiesto de recursos estáticos en tiempo de compilación que MapStaticAssets sirve. Agregue UseStaticFiles después de UseDefaultFiles, como se muestra en el ejemplo anterior, para servir documentos predeterminados.

En el flujo de procesamiento de solicitudes, antes de la llamada existente a UseStaticFiles:

app.UseDefaultFiles();

Con UseDefaultFiles, las solicitudes a una carpeta en wwwroot buscan:

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

El primer archivo que se encuentra en la lista se sirve como si la solicitud incluyera el nombre de archivo. La dirección URL del explorador sigue reflejando el URI solicitado.

El código siguiente cambia el nombre de archivo predeterminado a default-document.html:

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

Combinar archivos estáticos, documentos predeterminados y exploración de directorios

UseFileServer combina la funcionalidad de UseStaticFiles y UseDefaultFiles y, opcionalmente, la de UseDirectoryBrowser.

En la canalización de procesamiento de solicitudes después de la llamada existente a MapStaticAssets (.NET 9 o posterior) o UseStaticFiles (.NET 8 o versiones anteriores), llame a UseFileServer para habilitar el servicio de archivos estáticos y el archivo predeterminado.

app.UseFileServer();

La exploración de directorios no está habilitada para el ejemplo anterior.

El código siguiente habilita el servicio de archivos estáticos, el archivo predeterminado y la exploración de directorios.

Registro del servicio:

builder.Services.AddDirectoryBrowser();

En la canalización de procesamiento de solicitudes, después de la llamada existente a UseStaticFiles:

app.UseFileServer(enableDirectoryBrowsing: true);

En Startup.ConfigureServices:

services.AddDirectoryBrowser();

En Startup.Configure, después de la llamada existente a UseStaticFiles:

app.UseFileServer(enableDirectoryBrowsing: true);

Para la dirección de host (/), UseFileServer devuelve el documento HTML predeterminado antes de la página predeterminada (Razor) o la vista MVC predeterminada Pages/Index.cshtml (Home/Index.cshtml).

Ten en cuenta la siguiente jerarquía de directorios:

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

El código siguiente habilita el servicio de archivos estáticos, el archivo predeterminado y la exploración de directorios de ExtraStaticFiles.

Espacios de nombres para la API siguiente:

using Microsoft.Extensions.FileProviders;

Registro del servicio:

builder.Services.AddDirectoryBrowser();

En la canalización de procesamiento de solicitudes, después de la llamada existente a UseStaticFiles:

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

Espacios de nombres para la API siguiente:

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

En Startup.ConfigureServices:

services.AddDirectoryBrowser();

En Startup.Configure, después de la llamada existente a UseStaticFiles:

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

Se debe llamar a AddDirectoryBrowser cuando el valor de la propiedad EnableDirectoryBrowsing es true.

Con la jerarquía de archivos y el código anteriores, las direcciones URL se resuelven como se muestra en la tabla siguiente (el marcador de posición {HOST} es el anfitrión).

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

Si no existe ningún archivo con nombre predeterminado en el ExtraStaticFiles directorio, https://{HOST}/static-files devuelve la lista de directorios con vínculos que se pueden hacer clic, donde el {HOST} marcador de posición es el host.

UseDefaultFiles y UseDirectoryBrowser realizan un redireccionamiento del lado cliente desde un URI de destino sin un / final a un URI de destino con un / final. Por ejemplo, de https://{HOST}/static-files (sin final /) a https://{HOST}/static-files/ (incluye un final /). Las direcciones URL relativas dentro del ExtraStaticFiles directorio no son válidas sin una barra diagonal final (/) a menos que se use la RedirectToAppendTrailingSlash opción de DefaultFilesOptions .

Asignar las extensiones de archivo a los tipos MIME

Note

Para obtener instrucciones que se aplican a las Blazor aplicaciones, consulte Archivos estáticos de ASP.NET CoreBlazor.

Usa FileExtensionContentTypeProvider.Mappings para agregar o modificar la extensión de archivo en las asignaciones de tipos de contenido MIME.

Note

FileExtensionContentTypeProvider no es seguro en entornos multihilo para escrituras concurrentes. Su diccionario de mapeos internos es un Dictionary<string, string> estándar no sincronizado. Las asignaciones del proveedor están pensadas para configurarse una sola vez durante el inicio. Si posteriormente solo se realizan operaciones de lectura (búsquedas), el proveedor puede registrarse de forma segura como un singleton. No añadas, elimines ni modifiques asignaciones una vez que el proveedor esté en uso por solicitudes simultáneas.

En el ejemplo siguiente, varias extensiones de archivo se asignan a tipos MIME conocidos. La .rtf extensión se reemplaza y .mp4 se quita:

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

...

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

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

Cuando tenga varias opciones de archivo estático para configurar, también puede establecer el proveedor mediante StaticFileOptions:

var provider = new FileExtensionContentTypeProvider();

...

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

app.UseStaticFiles();

En Startup.Configure:

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

...

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

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

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

Para obtener más información, consulte Tipos de contenido MIME.

Tipos de contenido no estándar

El middleware de archivos estáticos comprende casi 400 tipos de contenido de archivo conocidos. Si el usuario solicita un archivo con un tipo de archivo desconocido, el middleware de archivos estático pasa la solicitud al siguiente middleware de la canalización. Si ningún middleware se ocupa de la solicitud, se devuelve una respuesta 404 No encontrado. Si se habilita la exploración de directorios, se muestra un vínculo al archivo en una lista de directorios.

El código siguiente permite atender tipos de contenido desconocidos y representa el archivo desconocido como una imagen:

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

Con el código anterior, una solicitud para un archivo con un tipo de contenido desconocido se devuelve como una imagen.

Warning

Habilitar ServeUnknownFileTypes supone un riesgo para la seguridad. Está deshabilitado de forma predeterminada y no se recomienda su uso. Asignar extensiones de archivo a tipos MIME proporciona una alternativa más segura al servicio de archivos con extensiones no estándar.

Proporcionar un manifiesto de archivos estáticos personalizados

Si staticAssetsManifestPath es null, IHostEnvironment.ApplicationName se usa para buscar el manifiesto. Como alternativa, especifique una ruta de acceso completa al archivo de manifiesto. Si se usa una ruta de acceso relativa, el entorno busca el archivo en AppContext.BaseDirectory.

Consideraciones de seguridad para archivos estáticos

Warning

UseDirectoryBrowser y UseStaticFiles pueden producir pérdidas de información confidencial. Se recomienda deshabilitar el examen de directorios en producción. Revisa cuidadosamente los directorios que se habilitan mediante UseStaticFiles o UseDirectoryBrowser. Todo el directorio y sus subdirectorios pasan a ser accesibles públicamente. Almacena los archivos adecuados para proporcionarlos al público en un directorio dedicado, como <content_root>/wwwroot. Separa estos archivos de las vistas MVC, de Razor Pages, de los archivos de configuración, etc.

  • Las direcciones URL para el contenido que se expone a través de UseDirectoryBrowser y UseStaticFiles están sujetas a la distinción entre mayúsculas y minúsculas, y a restricciones de caracteres del sistema de archivos subyacente. Por ejemplo, Windows no distingue entre mayúsculas y minúsculas, pero macOS y Linux sí.

  • Las aplicaciones de ASP.NET Core hospedadas en IIS usan el módulo de ASP.NET Core para reenviar todas las solicitudes a la aplicación, incluidas las solicitudes de archivos estáticos. No se utiliza el controlador de archivos estáticos de IIS y no tiene la posibilidad de controlar las solicitudes.

  • Completa los pasos siguientes en el Administrador de IIS para quitar el controlador de archivos estáticos de IIS en el nivel de servidor o de sitio web:

    1. Navega hasta la característica Módulos.
    2. En la lista, selecciona StaticFileModule.
    3. Haz clic en Quitar en la barra lateral Acciones.

Warning

Si el controlador de archivos estáticos de IIS está habilitado y el módulo de ASP.NET Core no está configurado correctamente, se proporcionan archivos estáticos. Esto sucede, por ejemplo, si el web.config archivo no está implementado.

  • Coloca los archivos de código (incluidos .cs y .cshtml) fuera de la raíz web del proyecto de la aplicación. Por lo tanto, se crea una separación lógica entre el contenido del lado cliente de la aplicación y el código basado en servidor. Esto impide que se filtre el código del lado servidor.

Propiedades de MSBuild

En las tablas siguientes se muestran las propiedades y descripciones de metadatos de los archivos estáticos de MSBuild.

Propiedad Description
EnableDefaultCompressedItems Habilita los patrones de inclusión y exclusión de compresión predeterminados.
CompressionIncludePatterns Lista separada por punto y coma de patrones de archivo que se van a incluir para la compresión.
CompressionExcludePatterns Lista separada por punto y coma de patrones de archivo que se excluirán de la compresión.
EnableDefaultCompressionFormats Habilita los formatos de compresión predeterminados (Gzip y Brotli).
BuildCompressionFormats Formatos de compresión que se usarán durante la compilación.
PublishCompressionFormats Formatos de compresión que se usarán durante la publicación.
DisableBuildCompression Deshabilita la compresión durante la compilación.
CompressDiscoveredAssetsDuringBuild Comprime los recursos detectados durante la compilación.
BrotliCompressionLevel Nivel de compresión para el algoritmo Brotli.
StaticWebAssetBuildCompressAllAssets Comprime todos los recursos durante la compilación, no solo los recursos detectados o calculados durante una compilación.
StaticWebAssetPublishCompressAllAssets Comprime todos los recursos durante la publicación, no solo los recursos detectados o calculados durante una compilación.
Propiedad Description
StaticWebAssetBasePath Ruta URL base para todos los recursos en una biblioteca.
StaticWebAssetsFingerprintContent Habilita la identificación de contenidos mediante huellas digitales para la eliminación de la caché.
StaticWebAssetFingerprintingEnabled Habilita la característica de huella digital para los recursos web estáticos.
StaticWebAssetsCacheDefineStaticWebAssetsEnabled Habilita el almacenamiento en caché para las definiciones de recursos web estáticos.
StaticWebAssetEndpointExclusionPattern Patrón para excluir puntos de conexión.
Grupo de artículos Description Metadatos
StaticWebAssetContentTypeMapping Asigna patrones de archivos a tipos de contenido y encabezados de caché para los puntos de conexión. Pattern, , Cache, Priority
StaticWebAssetFingerprintPattern Define patrones para aplicar identificadores únicos a recursos web estáticos para la invalidación de caché. Pattern, Expression

Descripciones de metadatos:

  • Pattern: Un patrón glob utilizado para buscar coincidencias en los archivos. Para StaticWebAssetContentTypeMapping, coincide con los archivos para determinar su tipo de contenido (por ejemplo, *.js para archivos JavaScript). Para StaticWebAssetFingerprintPattern, identifica archivos de varias extensiones que requieren un tratamiento especial de huellas digitales (por ejemplo, *.lib.module.js).

  • Cache: especifica el valor de Cache-Control encabezado para el tipo de contenido coincidente. Esto controla el comportamiento del almacenamiento en caché del explorador (por ejemplo, max-age=3600, must-revalidate para archivos multimedia).

  • Priority: controla la prioridad cuando varios StaticWebAssetContentTypeMapping elementos coinciden con el mismo archivo. Los valores numéricos más altos tienen prioridad sobre los más bajos. Priority es obligatorio.

  • Expression: define cómo se inserta la huella digital en el nombre de archivo. El valor predeterminado es #[.{FINGERPRINT}], que inserta el identificador único (marcador de posición {FINGERPRINT}) antes de la extensión.

En el ejemplo siguiente, se asigna el patrón de archivo bitmap (.bmp) al tipo de contenido image/bmp con el marcador de posición {CACHE HEADER} que representa el encabezado Cache-Control que se utilizará para los puntos de conexión sin huella digital.

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

Opciones de configuración en tiempo de ejecución

En la tabla siguiente se describen las opciones de configuración en tiempo de ejecución.

Clave de configuración Description
ReloadStaticAssetsAtRuntime Habilita la recarga en caliente de recursos estáticos durante el desarrollo: sirve los archivos modificados de la raíz web (wwwroot) (vuelve a calcular ETag y los vuelve a comprimir si es necesario) en lugar de las versiones del manifiesto de la compilación. Por defecto se habilita solo cuando se presenta un manifiesto de compilación, a menos que se configure explícitamente.
DisableStaticAssetNotFoundRuntimeFallback Cuando true, suprime el punto de conexión alternativo que sirve los archivos recién agregados que no están presentes en el manifiesto de compilación. Cuando false o ausente, una comprobación de la existencia del archivo {**path} con reserva (GET/HEAD) registra una advertencia y sirve el archivo con un ETag calculado.
EnableStaticAssetsDevelopmentCaching Cuando es true, conserva los encabezados Cache-Control originales en los descriptores de recursos. Cuando false está ausente, reescribe los encabezados Cache-Control a no-cache para evitar el almacenamiento en caché agresivo del cliente durante el desarrollo.
EnableStaticAssetsDevelopmentIntegrity Cuando true, mantiene las propiedades de integridad en los descriptores de activos. Cuando false falta o está ausente, elimina cualquier propiedad de integridad para evitar desajustes cuando los archivos cambian durante el desarrollo.

Recursos adicionales