Visualizzare immagini e documenti in ASP.NET Core Blazor
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere Criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Importante
Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Questo articolo descrive gli approcci per la visualizzazione di immagini e documenti nelle Blazor app.
Gli esempi in questo articolo sono disponibili per l'ispezione e l'uso Blazor nelle app di esempio:
dotnet/blazor-samples
Repository GitHub: passare all'app denominata BlazorSample_BlazorWebApp
(8.0 o versione successiva), BlazorSample_Server
(7.0 o versioni precedenti) o BlazorSample_WebAssembly
.
Impostare dinamicamente un'origine immagine
L'esempio seguente illustra come impostare dinamicamente l'origine di un'immagine con un campo C#.
L'esempio in questa sezione usa tre file di immagine, denominati image1.png
, image2.png
e image3.png
. Le immagini vengono inserite in una cartella denominata images
nella radice Web dell'app (wwwroot
). L'uso della images
cartella è solo a scopo dimostrativo. È possibile organizzare gli asset statici in qualsiasi layout di cartella preferito, inclusa la gestione degli asset direttamente dalla wwwroot
cartella.
Nel componente ShowImage1
seguente:
- L'origine dell'immagine (
src
) viene impostata dinamicamente sul valore diimageSource
in C#. - Il
ShowImage
metodo aggiorna ilimageSource
campo in base a un argomento immagineid
passato al metodo . - I pulsanti sottoposti a rendering chiamano il
ShowImage
metodo con un argomento immagine per ognuna delle tre immagini disponibili nellaimages
cartella. Il nome del file è composto usando l'argomento passato al metodo e corrisponde a una delle tre immagini nellaimages
cartella.
ShowImage1.razor
:
@page "/show-image-1"
<PageTitle>Show Image 1</PageTitle>
<h1>Show Image Example 1</h1>
@if (imageSource is not null)
{
<p>
<img src="@imageSource" />
</p>
}
@for (var i = 1; i <= 3; i++)
{
var imageId = i;
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
@code {
private string? imageSource;
private void ShowImage(int id) => imageSource = $"images/image{id}.png";
}
@page "/show-image-1"
<PageTitle>Show Image 1</PageTitle>
<h1>Show Image Example 1</h1>
@if (imageSource is not null)
{
<p>
<img src="@imageSource" />
</p>
}
@for (var i = 1; i <= 3; i++)
{
var imageId = i;
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
@code {
private string? imageSource;
private void ShowImage(int id) => imageSource = $"images/image{id}.png";
}
@page "/show-image-1"
<h1>Dynamic Image Source Example</h1>
@if (imageSource is not null)
{
<p>
<img src="@imageSource" />
</p>
}
@for (var i = 1; i <= 3; i++)
{
var imageId = i;
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
@code {
private string? imageSource;
private void ShowImage(int id)
{
imageSource = $"images/image{id}.png";
}
}
@page "/show-image-1"
<h1>Dynamic Image Source Example</h1>
@if (imageSource is not null)
{
<p>
<img src="@imageSource" />
</p>
}
@for (var i = 1; i <= 3; i++)
{
var imageId = i;
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
@code {
private string? imageSource;
private void ShowImage(int id)
{
imageSource = $"images/image{id}.png";
}
}
L'esempio precedente usa un campo C# per contenere i dati di origine dell'immagine, ma è anche possibile usare una proprietà C# per contenere i dati.
Evitare di usare una variabile di ciclo direttamente in un'espressione lambda, ad esempio i
nell'esempio di ciclo precedente for
. In caso contrario, la stessa variabile viene usata da tutte le espressioni lambda, che comporta l'uso dello stesso valore in tutte le espressioni lambda. Acquisire il valore della variabile in una variabile locale. Nell'esempio precedente:
- La variabile
i
di ciclo viene assegnata aimageId
. imageId
viene usato nell'espressione lambda.
In alternativa, usare un foreach
ciclo con Enumerable.Range, che non soffre del problema precedente:
@foreach (var imageId in Enumerable.Range(1, 3))
{
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
Per altre informazioni sulle espressioni lambda con la gestione degli eventi, vedere gestione degli eventi ASP.NET CoreBlazor.
Trasmettere dati di immagine o documento
Un'immagine o un altro tipo di documento, ad esempio un PDF, può essere trasmessa direttamente al client usando Blazorle funzionalità di interoperabilità di streaming anziché ospitare il file in un URL pubblico.
L'esempio in questa sezione trasmette i dati di origine usando l'interoperabilità JavaScript (JS). La funzione seguente setSource
JS :
- Può essere usato per trasmettere il contenuto per gli elementi seguenti: , ,
<img>
, ,<object>
<link>
,<script>
, ,<style>
, e<track>
.<iframe>
<embed>
<body>
- Accetta un elemento
id
per visualizzare il contenuto del file, un flusso di dati per il documento, il tipo di contenuto e un titolo per l'elemento di visualizzazione.
La funzione :
- Legge il flusso fornito in un oggetto
ArrayBuffer
. - Crea un
Blob
oggetto per eseguire il wrapping diArrayBuffer
, impostando il tipo di contenuto del BLOB. - Crea un URL dell'oggetto da usare come indirizzo per il documento da visualizzare.
- Imposta il titolo dell'elemento (
title
) daltitle
parametro e imposta l'origine dell'elemento (src
) dall'URL dell'oggetto creato. - Per evitare perdite di memoria, la funzione chiama
revokeObjectURL
per eliminare l'URL dell'oggetto dopo che l'elemento carica la risorsa (load
evento).
<script>
window.setSource = async (elementId, stream, contentType, title) => {
const arrayBuffer = await stream.arrayBuffer();
let blobOptions = {};
if (contentType) {
blobOptions['type'] = contentType;
}
const blob = new Blob([arrayBuffer], blobOptions);
const url = URL.createObjectURL(blob);
const element = document.getElementById(elementId);
element.title = title;
element.onload = () => {
URL.revokeObjectURL(url);
}
element.src = url;
}
</script>
Nota
Per indicazioni generali sulla JS posizione e i suggerimenti per le app di produzione, vedere Posizione JavaScript nelle app ASP.NET CoreBlazor.
Componente seguente ShowImage2
:
- Inserisce i servizi per un oggetto System.Net.Http.HttpClient e Microsoft.JSInterop.IJSRuntime.
- Include un
<img>
tag per visualizzare un'immagine. - Dispone di un
GetImageStreamAsync
metodo C# per recuperare un oggetto Stream per un'immagine. Un'app di produzione può generare dinamicamente un'immagine in base all'utente specifico o recuperare un'immagine dall'archiviazione. L'esempio seguente recupera l'avatar .NET per ildotnet
repository GitHub. - Dispone di un
SetImageAsync
metodo attivato dalla selezione del pulsante da parte dell'utente.SetImageAsync
esegue i passaggi seguenti:- Recupera l'oggetto Stream da
GetImageStreamAsync
. - Esegue il wrapping di Stream in un DotNetStreamReferenceoggetto , che consente di trasmettere i dati dell'immagine al client.
- Richiama la
setSource
funzione JavaScript, che accetta i dati nel client.
- Recupera l'oggetto Stream da
Nota
Le app lato server usano un servizio dedicato HttpClient per effettuare richieste, quindi non è richiesta alcuna azione da parte dello sviluppatore di un'app lato Blazor server per registrare un HttpClient servizio. Le app sul lato client hanno una registrazione del servizio predefinita HttpClient quando l'app viene creata da un Blazor modello di progetto. Se una HttpClient registrazione del servizio non è presente nel Program
file di un'app lato client, specificarne una aggiungendo builder.Services.AddHttpClient();
. Per altre informazioni, vedere Effettuare richieste HTTP usando IHttpClientFactory in ASP.NET Core.
ShowImage2.razor
:
@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS
<PageTitle>Show Image 2</PageTitle>
<h1>Show Image Example 2</h1>
<button @onclick="SetImageAsync">
Set Image
</button>
<div class="p-3">
<img id="avatar" />
</div>
@code {
private async Task<Stream> GetImageStreamAsync() =>
await Http.GetStreamAsync("https://avatars.githubusercontent.com/u/9141961");
private async Task SetImageAsync()
{
var imageStream = await GetImageStreamAsync();
var strRef = new DotNetStreamReference(imageStream);
await JS.InvokeVoidAsync("setSource", "avatar", strRef, "image/png",
".NET GitHub avatar");
}
}
@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS
<PageTitle>Show Image 2</PageTitle>
<h1>Show Image Example 2</h1>
<button @onclick="SetImageAsync">
Set Image
</button>
<div class="p-3">
<img id="avatar" />
</div>
@code {
private async Task<Stream> GetImageStreamAsync() =>
await Http.GetStreamAsync("https://avatars.githubusercontent.com/u/9141961");
private async Task SetImageAsync()
{
var imageStream = await GetImageStreamAsync();
var strRef = new DotNetStreamReference(imageStream);
await JS.InvokeVoidAsync("setSource", "avatar", strRef, "image/png",
".NET GitHub avatar");
}
}
@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS
<h1>Show Image Example 2</h1>
<button @onclick="SetImageAsync">
Set Image
</button>
<div class="p-3">
<img id="avatar" />
</div>
@code {
private async Task<Stream> GetImageStreamAsync()
{
return await Http.GetStreamAsync(
"https://avatars.githubusercontent.com/u/9141961");
}
private async Task SetImageAsync()
{
var imageStream = await GetImageStreamAsync();
var strRef = new DotNetStreamReference(imageStream);
await JS.InvokeVoidAsync("setSource", "avatar", strRef, "image/png",
".NET GitHub avatar");
}
}
@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS
<h1>Show Image Example 2</h1>
<button @onclick="SetImageAsync">
Set Image
</button>
<div class="p-3">
<img id="avatar" />
</div>
@code {
private async Task<Stream> GetImageStreamAsync()
{
return await Http.GetStreamAsync(
"https://avatars.githubusercontent.com/u/9141961");
}
private async Task SetImageAsync()
{
var imageStream = await GetImageStreamAsync();
var strRef = new DotNetStreamReference(imageStream);
await JS.InvokeVoidAsync("setSource", "avatar", strRef, "image/png",
".NET GitHub avatar");
}
}
Il componente seguente ShowFile
carica un file di testo (files/quote.txt
) o un file PDF (files/quote.pdf
) in un <iframe>
elemento (documentazione MDN).
Attenzione
L'uso dell'elemento nell'esempio <iframe>
seguente è sicuro e non richiede la sandboxing perché il contenuto viene caricato dall'app, che è un'origine attendibile.
Quando si carica il contenuto da un'origine o un input utente non attendibile, un elemento implementato <iframe>
in modo non corretto rischia di creare vulnerabilità di sicurezza.
ShowFile.razor
:
@page "/show-file"
@inject NavigationManager Navigation
@inject HttpClient Http
@inject IJSRuntime JS
<PageTitle>Show File</PageTitle>
<div class="d-flex flex-column">
<h1>Show File Example</h1>
<div class="mb-4">
<button @onclick="@(() => ShowFileAsync("files/quote.txt",
"General Ravon quote (text file)"))">
Show text ('quote.txt')
</button>
<button @onclick="@(() => ShowFileAsync("files/quote.pdf",
"General Ravon quote (PDF file)"))">
Show PDF ('quote.pdf')
</button>
</div>
<iframe id="iframe" style="height: calc(100vh - 200px)" />
</div>
@code
{
private async Task<(Stream, string?)> DownloadFileAsync(string url)
{
var absoluteUrl = Navigation.ToAbsoluteUri(url);
Console.WriteLine($"Downloading file from {absoluteUrl}");
var response = await Http.GetAsync(absoluteUrl);
string? contentType = null;
if (response.Content.Headers.TryGetValues("Content-Type", out var values))
{
contentType = values.FirstOrDefault();
}
return (await response.Content.ReadAsStreamAsync(), contentType);
}
private async Task ShowFileAsync(string url, string title)
{
var (fileStream, contentType) = await DownloadFileAsync(url);
var strRef = new DotNetStreamReference(fileStream);
await JS.InvokeVoidAsync("setSource", "iframe", strRef, contentType, title);
}
}
@page "/show-file"
@inject NavigationManager Navigation
@inject HttpClient Http
@inject IJSRuntime JS
<PageTitle>Show File</PageTitle>
<div class="d-flex flex-column">
<h1>Show File Example</h1>
<div class="mb-4">
<button @onclick="@(() => ShowFileAsync("files/quote.txt",
"General Ravon quote (text file)"))">
Show text ('quote.txt')
</button>
<button @onclick="@(() => ShowFileAsync("files/quote.pdf",
"General Ravon quote (PDF file)"))">
Show PDF ('quote.pdf')
</button>
</div>
<iframe id="iframe" style="height: calc(100vh - 200px)" />
</div>
@code
{
private async Task<(Stream, string?)> DownloadFileAsync(string url)
{
var absoluteUrl = Navigation.ToAbsoluteUri(url);
Console.WriteLine($"Downloading file from {absoluteUrl}");
var response = await Http.GetAsync(absoluteUrl);
string? contentType = null;
if (response.Content.Headers.TryGetValues("Content-Type", out var values))
{
contentType = values.FirstOrDefault();
}
return (await response.Content.ReadAsStreamAsync(), contentType);
}
private async Task ShowFileAsync(string url, string title)
{
var (fileStream, contentType) = await DownloadFileAsync(url);
var strRef = new DotNetStreamReference(fileStream);
await JS.InvokeVoidAsync("setSource", "iframe", strRef, contentType, title);
}
}
@page "/show-file"
@inject NavigationManager NavigationManager
@inject HttpClient Http
@inject IJSRuntime JS
<div class="d-flex flex-column">
<h1>Show File Example</h1>
<div class="mb-4">
<button @onclick="@(() => ShowFileAsync("files/quote.txt",
"General Ravon quote (text file)"))">
Show text ('quote.txt')
</button>
<button @onclick="@(() => ShowFileAsync("files/quote.pdf",
"General Ravon quote (PDF file)"))">
Show PDF ('quote.pdf')
</button>
</div>
<iframe id="iframe" style="height: calc(100vh - 200px)" />
</div>
@code
{
private async Task<(Stream, string?)> DownloadFileAsync(string url)
{
var absoluteUrl = NavigationManager.ToAbsoluteUri(url);
Console.WriteLine($"Downloading file from {absoluteUrl}");
var response = await Http.GetAsync(absoluteUrl);
string? contentType = null;
if (response.Content.Headers.TryGetValues("Content-Type", out var values))
{
contentType = values.FirstOrDefault();
}
return (await response.Content.ReadAsStreamAsync(), contentType);
}
private async Task ShowFileAsync(string url, string title)
{
var (fileStream, contentType) = await DownloadFileAsync(url);
var strRef = new DotNetStreamReference(fileStream);
await JS.InvokeVoidAsync("setSource", "iframe", strRef, contentType, title);
}
}
@page "/show-file"
@inject NavigationManager NavigationManager
@inject HttpClient Http
@inject IJSRuntime JS
<div class="d-flex flex-column">
<h1>Show File Example</h1>
<div class="mb-4">
<button @onclick="@(() => ShowFileAsync("files/quote.txt",
"General Ravon quote (text file)"))">
Show text ('quote.txt')
</button>
<button @onclick="@(() => ShowFileAsync("files/quote.pdf",
"General Ravon quote (PDF file)"))">
Show PDF ('quote.pdf')
</button>
</div>
<iframe id="iframe" style="height: calc(100vh - 200px)" />
</div>
@code
{
private async Task<(Stream, string?)> DownloadFileAsync(string url)
{
var absoluteUrl = NavigationManager.ToAbsoluteUri(url);
Console.WriteLine($"Downloading file from {absoluteUrl}");
var response = await Http.GetAsync(absoluteUrl);
string? contentType = null;
if (response.Content.Headers.TryGetValues("Content-Type", out var values))
{
contentType = values.FirstOrDefault();
}
return (await response.Content.ReadAsStreamAsync(), contentType);
}
private async Task ShowFileAsync(string url, string title)
{
var (fileStream, contentType) = await DownloadFileAsync(url);
var strRef = new DotNetStreamReference(fileStream);
await JS.InvokeVoidAsync("setSource", "iframe", strRef, contentType, title);
}
}
Risorse aggiuntive
- ASP.NET caricamenti di file di base Blazor
- Caricamenti di file: caricare l'anteprima dell'immagine
- download di file core Blazor ASP.NET
- Chiamare metodi .NET da funzioni JavaScript in ASP.NET Core Blazor
- Chiamare funzioni JavaScript da metodi .NET in ASP.NET Core Blazor
- Blazorrepository GitHub di esempi () (
dotnet/blazor-samples
come scaricare)