Compartir a través de


Archivos estáticos Blazor en ASP.NET Core

Nota

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

Advertencia

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 9 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulte la versión de .NET 9 de este artículo.

En este artículo se describe la configuración de la aplicación Blazor para servir archivos estáticos.

Para obtener información general sobre cómo servir archivos estáticos utilizando las convenciones de puntos de enlace de enrutamiento para mapear recursos estáticos, consulte Mapear archivos estáticos en ASP.NET Core antes de leer este artículo.

Entrega de recursos estáticos en aplicaciones Blazor del lado del servidor

El servicio de recursos estáticos se gestiona mediante convenciones de enrutamiento de puntos finales o mediante un middleware, tal como se describe en la tabla a continuación.

Característica Interfaz de Programación de Aplicaciones (API) Versión de .NET Descripción
Mapeo de convenciones de puntos de enrutamiento de recursos estáticos MapStaticAssets .NET 9 o posterior Optimiza la entrega de recursos estáticos a los clientes.
Middleware de archivos estáticos UseStaticFiles Todas las versiones de .NET Proporciona activos estáticos a los clientes sin las optimizaciones de Map Static Assets, pero es útil para algunas tareas que Map Static Assets no es capaz de gestionar.

Los activos estáticos del mapa pueden reemplazar UseStaticFiles en la mayoría de las situaciones. Sin embargo, Map Static Assets está optimizado para distribuir los activos estáticos desde ubicaciones conocidas de la aplicación en el momento de la compilación y publicación. Si la aplicación atiende recursos de otras ubicaciones, como el disco o los recursos incrustados, debe usarse UseStaticFiles.

Map Static Assets (MapStaticAssets) reemplaza el uso de UseBlazorFrameworkFiles dentro de aplicaciones que sirven archivos de framework Blazor WebAssembly, y no es necesario llamar explícitamente a UseBlazorFrameworkFiles en Blazor Web App, ya que la API se llama automáticamente cuando se invoca AddInteractiveWebAssemblyComponents.

Cuando están habilitados los modos de renderizado Interactive WebAssembly o Interactive Auto:

  • Blazor crea un punto de conexión para exponer la colección de recursos como un módulo JS.
  • La URL se emite en el cuerpo de la solicitud como estado persistente del componente cuando un componente WebAssembly se renderiza en la página.
  • Durante el arranque de WebAssembly, Blazor recupera la URL, importa el módulo y llama a una función para recuperar la colección de activos y reconstruirla en memoria. La URL es específica del contenido y se almacena en caché para siempre, por lo que este coste general solo se paga una vez por usuario hasta que se actualiza la aplicación.
  • La colección de recursos también se expone en una URL legible por humanos (_framework/resource-collection.js), por lo que JS tiene acceso a la colección de recursos para mejorar la navegación o para implementar características de otros frameworks y componentes de terceros.

El middleware de archivos estáticos (UseStaticFiles) es útil en las siguientes situaciones que la asignación de activos estáticos (MapStaticAssets) no puede manejar:

Para obtener más información, vea Archivos estáticos en ASP.NET Core.

Entrega de activos con las convenciones del punto de conexión de enrutamiento de Map Static Assets

Esta sección se aplica a las aplicaciones Blazor del lado del servidor.

Los recursos se entregan a través de la propiedad ComponentBase.Assets, que resuelve la URL con identificador único de un recurso determinado. En el ejemplo siguiente, Bootstrap, la Blazor hoja de estilos de la aplicación de plantilla de proyecto (app.css) y la hoja de estilos de aislamiento CSS (basada en el espacio de nombres de una aplicación de BlazorSample) están vinculadas en un componente raíz, normalmente el App (Components/App.razor):

<link rel="stylesheet" href="@Assets["bootstrap/bootstrap.min.css"]" />
<link rel="stylesheet" href="@Assets["app.css"]" />
<link rel="stylesheet" href="@Assets["BlazorSample.styles.css"]" />

Importación de mapas

Esta sección se aplica a las aplicaciones Blazor del lado del servidor.

El componente Importar mapa (ImportMap) representa un elemento de mapa de importación (<script type="importmap"></script>) que define el mapa de importación para los scripts de módulo. El componente Mapa de importación se coloca en <head> contenido del componente raíz, normalmente el App (Components/App.razor).

<ImportMap />

Nota

En Blazor Web App que adoptan representación global de WebAssembly interactiva, el componente ImportMap no tiene ningún propósito y se puede quitar del componente App. Para obtener más información, vea los comentarios introductorios de este artículo.

Si no se asigna un elemento personalizado ImportMapDefinition a un componente importar mapa, el mapa de importación se genera en función de los recursos de la aplicación.

Los siguientes ejemplos muestran definiciones de asignación de importación personalizadas y las asignaciones de importación que crean.

Mapa básico de importación:

new ImportMapDefinition(
    new Dictionary<string, string>
    {
        { "jquery", "https://cdn.example.com/jquery.js" },
    },
    null,
    null);

El código anterior da como resultado el siguiente mapa de importación:

{
  "imports": {
    "jquery": "https://cdn.example.com/jquery.js"
  }
}

Mapa de importación con ámbito específico

new ImportMapDefinition(
    null,
    new Dictionary<string, IReadOnlyDictionary<string, string>>
    {
        ["/scoped/"] = new Dictionary<string, string>
        {
            { "jquery", "https://cdn.example.com/jquery.js" },
        }
    },
    null);

El código anterior da como resultado el siguiente mapa de importación:

{
  "scopes": {
    "/scoped/": {
      "jquery": "https://cdn.example.com/jquery.js"
    }
  }
}

Importar mapa con integridad.

new ImportMapDefinition(
    new Dictionary<string, string>
    {
        { "jquery", "https://cdn.example.com/jquery.js" },
    },
    null,
    new Dictionary<string, string>
    {
        { "https://cdn.example.com/jquery.js", "sha384-abc123" },
    });

El código anterior da como resultado el siguiente mapa de importación:

{
  "imports": {
    "jquery": "https://cdn.example.com/jquery.js"
  },
  "integrity": {
    "https://cdn.example.com/jquery.js": "sha384-abc123"
  }
}

Combina las definiciones de mapas de importación (ImportMapDefinition) con ImportMapDefinition.Combine.

Mapa de importación creado a partir de un ResourceAssetCollection que asigna activos estáticos a sus URLs únicas correspondientes.

ImportMapDefinition.FromResourceCollection(
    new ResourceAssetCollection(
    [
        new ResourceAsset(
            "jquery.fingerprint.js",
            [
                new ResourceAssetProperty("integrity", "sha384-abc123"),
                new ResourceAssetProperty("label", "jquery.js"),
            ])
    ]));

El código anterior produce el siguiente mapa de importación.

{
  "imports": {
    "./jquery.js": "./jquery.fingerprint.js"
  },
  "integrity": {
    "jquery.fingerprint.js": "sha384-abc123"
  }
}

Configura el middleware de archivos estáticos para servir recursos estáticos a los clientes mediante una llamada al UseStaticFiles en la canalización de procesamiento de solicitudes de la aplicación. Para obtener más información, vea Archivos estáticos en ASP.NET Core.

En versiones anteriores a .NET 8, los archivos estáticos del marco Blazor, como el script de Blazor, se sirven mediante el middleware de archivos estáticos. En .NET 8 o versiones posteriores, los archivos estáticos del marco Blazor se asignan mediante el enrutamiento de puntos de conexión y ya no se usa middleware de archivos estáticos.

Esta sección se aplica a todas las versiones Blazor y aplicaciones .NET.

En las tablas siguientes se resumen los formatos de archivos estáticos <link>href por versión de .NET.

Para conocer la ubicación del contenido <head> donde se colocan los enlaces a archivos estáticos, consulte Estructura del proyecto ASP.NET Core Blazor. Los enlaces de activos estáticos también pueden suministrarse mediante componentes <HeadContent> incluidos en componentes Razor individuales.

Para conocer la ubicación del contenido <head> donde se colocan los enlaces a archivos estáticos, consulte Estructura del proyecto ASP.NET Core Blazor.

.NET 9 o posterior

Tipo de aplicación href valor Ejemplos
Blazor Web App @Assets["{PATH}"] <link rel="stylesheet" href="@Assets["app.css"]" />
<link href="@Assets["_content/ComponentLib/styles.css"]" rel="stylesheet" />
Blazor Server† @Assets["{PATH}"] <link href="@Assets["css/site.css"]" rel="stylesheet" />
<link href="@Assets["_content/ComponentLib/styles.css"]" rel="stylesheet" />
Independiente Blazor WebAssembly {PATH} <link rel="stylesheet" href="css/app.css" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />

.NET 8.x

Tipo de aplicación href valor Ejemplos
Blazor Web App {PATH} <link rel="stylesheet" href="app.css" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />
Blazor Server† {PATH} <link href="css/site.css" rel="stylesheet" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />
Independiente Blazor WebAssembly {PATH} <link rel="stylesheet" href="css/app.css" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />

.NET 7.x o versiones anteriores

Tipo de aplicación href valor Ejemplos
Blazor Server† {PATH} <link href="css/site.css" rel="stylesheet" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />
Hospedado Blazor WebAssembly‡ {PATH} <link href="css/app.css" rel="stylesheet" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />
Blazor WebAssembly {PATH} <link href="css/app.css" rel="stylesheet" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />

†Blazor Server es compatible con .NET 8 o posterior, pero ya no es una plantilla de proyecto después de .NET 7.
‡Recomendamos actualizar las aplicaciones Blazor WebAssembly hospedadas a Blazor Web App cuando se adopte .NET 8 o una versión posterior.

Modo de proyecto de activos web estáticos

Esta sección se aplica al proyecto .Client de una Blazor Web App.

La configuración <StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode> necesaria en el proyecto .Client de una Blazor Web App revierte los comportamientos de recursos estáticos de Blazor WebAssembly a los valores predeterminados, de modo que el proyecto se comporte como parte del proyecto hospedado. El SDK Blazor WebAssembly (Microsoft.NET.Sdk.BlazorWebAssembly) configura los recursos web estáticos de una manera específica de trabajar en modo "independiente" con un servidor que simplemente consume las salidas de la biblioteca. Esto no es adecuado para un objeto Blazor Web App, donde la parte WebAssembly de la aplicación es una parte lógica del host y debe comportarse más como una biblioteca. Por ejemplo, el proyecto no expone el conjunto de estilos (por ejemplo, BlazorSample.Client.styles.css) y, en su lugar, solo proporciona el host con el lote de proyectos, para que el host pueda incluirlo en su propio conjunto de estilos.

Cambiar el valor (Default) de <StaticWebAssetProjectMode> o quitar la propiedad del proyecto .Client no se admite.

Archivos estáticos en entornos no-Development

Esta sección se aplica a los archivos estáticos del lado servidor.

Cuando se ejecuta una aplicación localmente, los recursos web estáticos solo están habilitados en el entorno de Development. Para habilitar los archivos estáticos para los entornos distintos de Development durante el desarrollo y las pruebas locales (por ejemplo, Staging), llama a UseStaticWebAssets en el WebApplicationBuilder del archivo Program.

Advertencia

Llama UseStaticWebAssets al entorno exacto para evitar la activación de la característica en producción, ya que sirve archivos de ubicaciones independientes en el disco que no sean del proyecto si se llama en un entorno de producción. En el ejemplo de esta sección se comprueba el entorno de Staging llamando a IsStaging.

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

Prefijo para recursos de Blazor WebAssembly

Esta sección es aplicable a Blazor Web App.

Use la opción WebAssemblyComponentsEndpointOptions.PathPrefix punto de conexión para establecer la cadena de ruta de acceso que indica el prefijo para los recursos de Blazor WebAssembly. La ruta de acceso debe corresponder a un proyecto de aplicación de Blazor WebAssembly al que se hace referencia.

endpoints.MapRazorComponents<App>()
    .AddInteractiveWebAssemblyRenderMode(options => 
        options.PathPrefix = "{PATH PREFIX}");

En el ejemplo anterior, el marcador de posición {PATH PREFIX} es el prefijo de ruta de acceso y debe comenzar con una barra diagonal (/).

En el ejemplo siguiente, el prefijo de ruta de acceso se establece en /path-prefix:

endpoints.MapRazorComponents<App>()
    .AddInteractiveWebAssemblyRenderMode(options => 
        options.PathPrefix = "/path-prefix");

Ruta base de los recursos web estáticos

Esta sección se aplica a las aplicaciones Blazor WebAssembly independientes.

La publicación de una aplicación Blazor coloca sus recursos estáticos, incluidos los archivos de marco de (recursos de carpeta de _framework), en la ruta raíz (/) en la salida publicada. La propiedad <StaticWebAssetBasePath> especificada en el archivo de proyecto (.csproj) establece la ruta de acceso base en una ruta de acceso no raíz:

<PropertyGroup>
  <StaticWebAssetBasePath>{PATH}</StaticWebAssetBasePath>
</PropertyGroup>

En el ejemplo anterior, el marcador de posición {PATH} es la ruta de acceso.

Sin establecer la propiedad <StaticWebAssetBasePath>, se publica una aplicación independiente en /BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/.

En los ejemplos anteriores, el marcador de posición {TFM} es el Moniker de la plataforma de destino (TFM) (por ejemplo, net6.0).

Si la propiedad <StaticWebAssetBasePath> en una aplicación Blazor WebAssembly independiente establece la ruta del recurso estático publicado en app1, la ruta raíz a la aplicación en la salida publicada es /app1.

En el archivo de proyecto de la aplicación independiente Blazor WebAssembly (.csproj):

<PropertyGroup>
  <StaticWebAssetBasePath>app1</StaticWebAssetBasePath>
</PropertyGroup>

En la salida publicada, la ruta de acceso a la aplicación independiente Blazor WebAssembly es /BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/app1/.

En los ejemplos anteriores, el marcador de posición {TFM} es el Moniker de la plataforma de destino (TFM) (por ejemplo, net6.0).

Esta sección se aplica a las aplicaciones Blazor WebAssembly independiente y a las soluciones de Blazor WebAssembly hospedadas.

La publicación de una aplicación Blazor coloca sus recursos estáticos, incluidos los archivos de marco de (recursos de carpeta de _framework), en la ruta raíz (/) en la salida publicada. La propiedad <StaticWebAssetBasePath> especificada en el archivo de proyecto (.csproj) establece la ruta de acceso base en una ruta de acceso no raíz:

<PropertyGroup>
  <StaticWebAssetBasePath>{PATH}</StaticWebAssetBasePath>
</PropertyGroup>

En el ejemplo anterior, el marcador de posición {PATH} es la ruta.

Sin establecer la propiedad <StaticWebAssetBasePath>, la aplicación cliente de una solución hospedada o una aplicación independiente se publica en las rutas de acceso siguientes:

  • En el proyecto Server de una solución de Blazor WebAssembly hospedada: /BlazorHostedSample/Server/bin/Release/{TFM}/publish/wwwroot/
  • En una aplicación Blazor WebAssembly independiente: /BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/

Si la propiedad <StaticWebAssetBasePath> en el proyecto Client de una aplicación Blazor WebAssembly hospedada o de una aplicación Blazor WebAssembly independiente establece la ruta del recurso estático publicado en app1, la ruta raíz a la aplicación en la salida publicada es /app1.

En el archivo del proyecto de la aplicación Client (.csproj) o en el archivo del proyecto de la aplicación Blazor WebAssembly independiente (.csproj):

<PropertyGroup>
  <StaticWebAssetBasePath>app1</StaticWebAssetBasePath>
</PropertyGroup>

En la salida publicada:

  • Ruta a la aplicación cliente en el proyecto Server de la solución de Blazor WebAssembly hospedada: /BlazorHostedSample/Server/bin/Release/{TFM}/publish/wwwroot/app1/
  • Ruta a una aplicación Blazor WebAssembly independiente: /BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/app1/

La propiedad <StaticWebAssetBasePath> se usa normalmente para controlar las rutas a los recursos estáticos publicados de varias aplicaciones Blazor WebAssembly en una sola implementación hospedada. Para más información, consulte Varias aplicaciones de ASP.NET Core Blazor WebAssembly hospedadas. La propiedad también es efectiva en aplicaciones Blazor WebAssembly independientes.

En los ejemplos anteriores, el marcador de posición {TFM} es el TARGET_FRAMEWORK Moniker (TFM) (por ejemplo, net6.0).

Asignaciones de archivos y opciones de archivo estático

Esta sección se aplica a los archivos estáticos del lado servidor.

Para crear mapas de archivos adicionales con un FileExtensionContentTypeProvider o configurar otros StaticFileOptions, use uno de los enfoques siguientes. En los ejemplos siguientes, el marcador de posición {EXTENSION} es la extensión de archivo y {CONTENT TYPE} es el tipo de contenido. El espacio de nombres de la API siguiente es Microsoft.AspNetCore.StaticFiles.

  • Configure las opciones a través de la inserción de dependencias (DI) en el archivo Program mediante StaticFileOptions:

    var provider = new FileExtensionContentTypeProvider();
    provider.Mappings["{EXTENSION}"] = "{CONTENT TYPE}";
    
    builder.Services.Configure<StaticFileOptions>(options =>
    {
        options.ContentTypeProvider = provider;
    });
    
    app.UseStaticFiles();
    
  • Pasa StaticFileOptions directamente a UseStaticFiles en el archivo Program:

    var provider = new FileExtensionContentTypeProvider();
    provider.Mappings["{EXTENSION}"] = "{CONTENT TYPE}";
    
    app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = provider });
    

Para crear asignaciones de archivos adicionales con un objeto FileExtensionContentTypeProvider o configurar otros valores StaticFileOptions, use uno de los enfoques siguientes. En los ejemplos siguientes, el marcador de posición {EXTENSION} es la extensión de archivo y {CONTENT TYPE} es el tipo de contenido.

  • Configure las opciones a través de la inserción de dependencias (DI) en el archivo Program mediante StaticFileOptions:

    using Microsoft.AspNetCore.StaticFiles;
    
    ...
    
    var provider = new FileExtensionContentTypeProvider();
    provider.Mappings["{EXTENSION}"] = "{CONTENT TYPE}";
    
    builder.Services.Configure<StaticFileOptions>(options =>
    {
        options.ContentTypeProvider = provider;
    });
    

    Este enfoque configura el mismo proveedor de archivos que se usa para servir el script Blazor. Asegúrese de que la configuración personalizada no interfiera con el servicio del script Blazor. Por ejemplo, no quite la asignación para los archivos JavaScript mediante la configuración del proveedor con provider.Mappings.Remove(".js").

  • Use dos llamadas a UseStaticFiles en el archivo Program:

    • Configure el proveedor de archivos personalizado en la primera llamada con StaticFileOptions.
    • El segundo middleware proporciona el script Blazor, que usa la configuración predeterminada de los archivos estáticos proporcionada por el marco Blazor.
    using Microsoft.AspNetCore.StaticFiles;
    
    ...
    
    var provider = new FileExtensionContentTypeProvider();
    provider.Mappings["{EXTENSION}"] = "{CONTENT TYPE}";
    
    app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = provider });
    app.UseStaticFiles();
    
  • Puede evitar interferir con el servicio de _framework/blazor.server.js mediante MapWhen para ejecutar un middleware de archivos estáticos personalizado:

    app.MapWhen(ctx => !ctx.Request.Path
        .StartsWithSegments("/_framework/blazor.server.js"),
            subApp => subApp.UseStaticFiles(new StaticFileOptions() { ... }));
    

Entrega de archivos desde varias ubicaciones

La guía de esta sección es aplicable solo a Blazor Web App.

Para servir archivos desde varias ubicaciones con un CompositeFileProvider:

Ejemplo:

Cree una carpeta en el proyecto de servidor denominada AdditionalStaticAssets. Coloque una imagen en la carpeta.

Agregue la siguiente instrucción using a la parte superior del archivo Program del proyecto de servidor:

using Microsoft.Extensions.FileProviders;

En el archivo Program del proyecto de servidor antesde la llamada a UseStaticFiles, agregue el siguiente código:

var secondaryProvider = new PhysicalFileProvider(
    Path.Combine(builder.Environment.ContentRootPath, "AdditionalStaticAssets"));
app.Environment.WebRootFileProvider = new CompositeFileProvider(
    app.Environment.WebRootFileProvider, secondaryProvider);

En el marcado del componente Home de la aplicación (Home.razor), haga referencia a la imagen con una etiqueta <img>:

<img src="{IMAGE FILE NAME}" alt="{ALT TEXT}" />

En el ejemplo anterior:

  • El marcador de posición {IMAGE FILE NAME} es el nombre del archivo de imagen. No es necesario proporcionar un segmento de ruta de acceso si el archivo de imagen está en la raíz de la carpeta AdditionalStaticAssets.
  • El marcador de posición {ALT TEXT} es el texto alternativo de la imagen.

Ejecutar la aplicación.

Recursos adicionales