Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
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 cómo consumir archivos de recursos estáticos en aplicaciones Blazor Hybrid.
En una aplicación Blazor Hybrid, los archivos estáticos son recursos de la aplicación, a los que acceden los componentes Razor mediante los métodos siguientes:
Cuando los recursos estáticos solo se usan en los componentes Razor, los recursos estáticos se pueden consumir desde la raíz web (carpeta wwwroot
) de forma similar a las aplicaciones Blazor WebAssembly y Blazor Server. Para obtener más información, consulta la sección Recursos estáticos limitados a componentesRazor.
.NET MAUI
En las aplicaciones .NET MAUI, los recursos sin procesar que usan la acción de compilación MauiAsset
y .NET MAUI file system helpers se usan para los recursos estáticos.
Nota
Las interfaces, las clases y los tipos auxiliares para trabajar con el almacenamiento en dispositivos en todas las plataformas admitidas para características como elegir un archivo, guardar preferencias y usar almacenamiento seguro se encuentran en el espacio de nombres Microsoft.Maui.Storage. El espacio de nombres está disponible en toda una aplicación Blazor Hybrid de MAUI, por lo que no es necesario especificar una instrucción using
en un archivo de clase o una directiva @using
Razor en un componente Razor para el espacio de nombres.
Coloca los recursos sin procesar en la carpeta Resources/Raw
de la aplicación. En el ejemplo de esta sección se usa un archivo de texto estático.
Resources/Raw/Data.txt
:
This is text from a static text file resource.
El componente Razor siguiente:
- Llama a OpenAppPackageFileAsync para obtener un Stream para el recurso.
- Lee Stream con StreamReader.
- Llama a StreamReader.ReadToEndAsync para leer el archivo.
Pages/StaticAssetExample.razor
:
@page "/static-asset-example"
@using System.IO
@using Microsoft.Extensions.Logging
@inject ILogger<StaticAssetExample> Logger
<h1>Static Asset Example</h1>
<p>@dataResourceText</p>
@code {
public string dataResourceText = "Loading resource ...";
protected override async Task OnInitializedAsync()
{
try
{
using var stream =
await FileSystem.OpenAppPackageFileAsync("Data.txt");
using var reader = new StreamReader(stream);
dataResourceText = await reader.ReadToEndAsync();
}
catch (FileNotFoundException ex)
{
dataResourceText = "Data file not found.";
Logger.LogError(ex, "'Resource/Raw/Data.txt' not found.");
}
}
}
Para obtener más información, consulta los siguientes recursos:
- Dirigirse a varias plataformas desde un único proyecto .NET MAUI (documentación .NET MAUI)
- Mejorar la coherencia con resizetizer (dotnet/maui #4367)
WPF
Coloca el recurso en una carpeta de la aplicación, normalmente en la raíz del proyecto, como una carpeta Resources
. En el ejemplo de esta sección se usa un archivo de texto estático.
Resources/Data.txt
:
This is text from a static text file resource.
Si una carpeta Properties
no existe en la aplicación, cree una carpeta Properties
en la raíz de la aplicación.
Si la carpeta Properties
no contiene un archivo de recursos (Resources.resx
), crea el archivo en Explorador de soluciones con el comando del menú contextual Agregar>Nuevo elemento.
Haz doble clic en el archivo Resource.resx
.
Selecciona Cadenas>Archivos en la lista desplegable.
Selecciona Agregar recurso>Agregar archivo existente. Si Visual Studio te pide que confirmes la edición del archivo, selecciona Sí. Ve a la carpeta Resources
, selecciona el archivo Data.txt
y selecciona Abrir.
En el componente de ejemplo siguiente, ResourceManager.GetString obtiene el texto del recurso de cadena para mostrar.
Advertencia
Nunca uses métodos ResourceManager con datos que no son de confianza.
StaticAssetExample.razor
:
@page "/static-asset-example"
@using System.Resources
<h1>Static Asset Example</h1>
<p>@dataResourceText</p>
@code {
public string dataResourceText = "Loading resource ...";
protected override void OnInitialized()
{
var resources =
new ResourceManager(typeof(WpfBlazor.Properties.Resources));
dataResourceText = resources.GetString("Data") ?? "'Data' not found.";
}
}
Windows Forms
Coloca el recurso en una carpeta de la aplicación, normalmente en la raíz del proyecto, como una carpeta Resources
. En el ejemplo de esta sección se usa un archivo de texto estático.
Resources/Data.txt
:
This is text from a static text file resource.
Examina los archivos asociados a Form1
en el Explorador de soluciones. Si Form1
no tienes un archivo de recursos (.resx
), agrega un archivo Form1.resx
con el comando de menú contextual Agregar>Nuevo elemento .
Haz doble clic en el archivo Form1.resx
.
Selecciona Cadenas>Archivos en la lista desplegable.
Selecciona Agregar recurso>Agregar archivo existente. Si Visual Studio te pide que confirmes la edición del archivo, selecciona Sí. Ve a la carpeta Resources
, selecciona el archivo Data.txt
y selecciona Abrir.
En el ejemplo de componente siguiente:
- El nombre del ensamblado de la aplicación es
WinFormsBlazor
. El nombre base de ResourceManager se establece en el nombre del ensamblado deForm1
(WinFormsBlazor.Form1
). - ResourceManager.GetString obtiene el texto del recurso de cadena para mostrar.
Advertencia
Nunca uses métodos ResourceManager con datos que no son de confianza.
StaticAssetExample.razor
:
@page "/static-asset-example"
@using System.Resources
<h1>Static Asset Example</h1>
<p>@dataResourceText</p>
@code {
public string dataResourceText = "Loading resource ...";
protected override async Task OnInitializedAsync()
{
var resources =
new ResourceManager("WinFormsBlazor.Form1", this.GetType().Assembly);
dataResourceText = resources.GetString("Data") ?? "'Data' not found.";
}
}
Recursos estáticos limitados a componentes Razor
Un control BlazorWebView
tiene un archivo host configurado (HostPage), normalmente wwwroot/index.html
. La ruta de acceso HostPage es relativa a la carpeta de proyecto. Todos los recursos web estáticos (scripts, archivos CSS, imágenes y otros archivos) a los que se hace referencia desde BlazorWebView
son relativos a su valor HostPage configurado.
Los recursos web estáticos de una biblioteca de clases (RCL) de Razor usan rutas de acceso especiales: _content/{PACKAGE ID}/{PATH AND FILE NAME}
. El marcador de posición {PACKAGE ID}
es el id. de paquete de la biblioteca. El id. de paquete tiene como valor predeterminado el nombre de ensamblado del proyecto si <PackageId>
no se especifica en el archivo del proyecto. El marcador de posición {PATH AND FILE NAME}
es la ruta de acceso y el nombre de archivo en wwwroot
. Estas rutas de acceso son subrutas lógicas de la carpeta wwwroot
de la aplicación, aunque realmente proceden de otros paquetes o proyectos. Los conjuntos de estilos CSS específicos de componentes también se compilan en la raíz de la carpeta wwwroot
.
La raíz web de HostPage determina qué subconjunto de recursos estáticos están disponibles:
wwwroot/index.html
(Recomendado): todos los recursos de la carpetawwwroot
de la aplicación están disponibles (por ejemplo:wwwroot/image.png
está disponible en/image.png
), incluidas las subcarpetas (por ejemplo:wwwroot/subfolder/image.png
está disponible en/subfolder/image.png
). Los recursos estáticos de RCL en la carpetawwwroot
de RCL están disponibles (por ejemplo:wwwroot/image.png
está disponible en la ruta de acceso_content/{PACKAGE ID}/image.png
), incluidas las subcarpetas (por ejemplo:wwwroot/subfolder/image.png
está disponible en la ruta de acceso_content/{PACKAGE ID}/subfolder/image.png
).wwwroot/{PATH}/index.html
: todos los recursos de la carpetawwwroot/{PATH}
de la aplicación están disponibles mediante rutas de acceso relativas raíz web de la aplicación. Los recursos estáticos RCL dewwwroot/{PATH}
no están disponibles porque estarían en una ubicación teórica inexistente, como../../_content/{PACKAGE ID}/{PATH}
, que no es una ruta de acceso relativa admitida.wwwroot/_content/{PACKAGE ID}/index.html
: todos los recursos de la carpetawwwroot/{PATH}
de RCL están disponibles mediante rutas de acceso relativas de raíz web RCL. Los recursos estáticos de la aplicación dewwwroot/{PATH}
no están disponibles porque estarían en una ubicación teórica inexistente, como../../{PATH}
, que no es una ruta de acceso relativa admitida.
Para la mayoría de las aplicaciones, se recomienda colocar HostPage en la raíz de la carpeta wwwroot
de la aplicación, lo que proporciona la mayor flexibilidad para proporcionar recursos estáticos de la aplicación, RCL y las subcarpetas de la aplicación y RCL.
En los ejemplos siguientes se muestra cómo hacer referencia a recursos estáticos desde la raíz web de la aplicación (carpeta wwwroot
) con una raíz HostPage en la carpeta wwwroot
.
wwwroot/data.txt
:
This is text from a static text file resource.
wwwroot/scripts.js
:
export function showPrompt(message) {
return prompt(message, 'Type anything here');
}
La siguiente imagen de Jeep® se usa también en el ejemplo de esta sección. Puedes hacer clic con el botón derecho en la imagen siguiente para guardarla localmente para usarla en una aplicación de prueba local.
wwwroot/jeep-yj.png
:
En un componente Razor:
- El contenido del archivo de texto estático se puede leer mediante las técnicas siguientes:
- .NET MAUI: .NET MAUI file system helpers (OpenAppPackageFileAsync)
- WPF y Windows Forms: StreamReader.ReadToEndAsync
- Los archivos JavaScript están disponibles en subrutas lógicas de
wwwroot
empleando rutas de acceso de./
. - La imagen puede ser el atributo de origen (
src
) de una etiqueta de imagen (<img>
).
StaticAssetExample2.razor
:
@page "/static-asset-example-2"
@using Microsoft.Extensions.Logging
@implements IAsyncDisposable
@inject IJSRuntime JS
@inject ILogger<StaticAssetExample2> Logger
<h1>Static Asset Example 2</h1>
<h2>Read a file</h2>
<p>@dataResourceText</p>
<h2>Call JavaScript</h2>
<p>
<button @onclick="TriggerPrompt">Trigger browser window prompt</button>
</p>
<p>@result</p>
<h2>Show an image</h2>
<p><img alt="1991 Jeep YJ" src="/jeep-yj.png" /></p>
<p>
<em>Jeep</em> and <em>Jeep YJ</em> are registered trademarks of
<a href="https://www.stellantis.com">FCA US LLC (Stellantis NV)</a>.
</p>
@code {
private string dataResourceText = "Loading resource ...";
private IJSObjectReference? module;
private string result;
protected override async Task OnInitializedAsync()
{
try
{
dataResourceText = await ReadData();
}
catch (FileNotFoundException ex)
{
dataResourceText = "Data file not found.";
Logger.LogError(ex, "'wwwroot/data.txt' not found.");
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./scripts.js");
}
}
private async Task TriggerPrompt()
{
result = await Prompt("Provide some text");
}
public async ValueTask<string> Prompt(string message) =>
module is not null ?
await module.InvokeAsync<string>("showPrompt", message) : null;
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
En las aplicaciones .NET MAUI, agrega el siguiente método ReadData
al bloque @code
del componente anterior:
private async Task<string> ReadData()
{
using var stream = await FileSystem.OpenAppPackageFileAsync("wwwroot/data.txt");
using var reader = new StreamReader(stream);
return await reader.ReadToEndAsync();
}
En aplicaciones WPF y Windows Forms, agregue el siguiente método ReadData
al bloque @code
del componente anterior:
private async Task<string> ReadData()
{
using var reader = new StreamReader("wwwroot/data.txt");
return await reader.ReadToEndAsync();
}
Los archivos JavaScript colocados también son accesibles en subrutas lógicas de wwwroot
. En lugar de usar el script descrito anteriormente para la función showPrompt
en wwwroot/scripts.js
, el siguiente archivo JavaScript colocado para el componente StaticAssetExample2
también hace que la función esté disponible.
Pages/StaticAssetExample2.razor.js
:
export function showPrompt(message) {
return prompt(message, 'Type anything here');
}
Modifica la referencia de objeto de módulo en el componente StaticAssetExample2
para usar la ruta de acceso del archivo JavaScript colocado (./Pages/StaticAssetExample2.razor.js
):
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Pages/StaticAssetExample2.razor.js");
Marcas comerciales
Jeep y Jeep YJ son marcas registradas de FCA US LLC (Stellantis NV).