Anzeigen von Bildern und Dokumenten in ASP.NET Core Blazor
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der Supportrichtlinie für .NET und .NET Core. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Wichtig
Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.
Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
In diesem Artikel werden Ansätze zum Anzeigen von Bildern und Dokumenten in Blazor-Apps beschrieben.
Die Beispiele in diesem Artikel können in den Blazor-Beispiel-Apps eingesehen und verwendet werden:
dotnet/blazor-samples
GitHub-Repository: Navigieren Sie zur App mit dem Namen BlazorSample_BlazorWebApp
(8.0 oder höher), BlazorSample_Server
(7.0 oder früher) oder BlazorSample_WebAssembly
.
Dynamisches Festlegen einer Bildquelle
Im folgenden Beispiel wird veranschaulicht, wie die Quelle eines Bilds dynamisch mit einem C#-Feld festgelegt wird.
In diesem Abschnitt werden drei Bilddateien mit den Namen image1.png
, image2.png
und image3.png
verwendet. Die Bilder werden in einem Ordner mit dem Namen images
im Web-Stammverzeichnis der App (wwwroot
) abgelegt. Die Verwendung des Ordners images
dient nur zur Demonstrationszwecken. Sie können statische Assets in jedem beliebigen Ordnerlayout organisieren, das Sie bevorzugen, einschließlich der Bereitstellung von Assets direkt aus dem wwwroot
-Ordner.
In der folgenden ShowImage1
-Komponente:
- Die Quelle des Bilds (
src
) wird in C# dynamisch auf den WertimageSource
festgelegt. - Mit der
ShowImage
-Methode wird dasimageSource
-Feld basierend auf einemid
-Bildargument aktualisiert, das an die Methode übergeben wird. - Die
ShowImage
-Methode wird von gerenderten Schaltflächen mit einem Bild-Argument für jedes der drei verfügbaren Bilder im Ordnerimages
aufgerufen. Der Dateiname besteht aus dem Argument, das an die Methode übergeben wird, und entspricht einem der drei Bilder imimages
Ordner.
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";
}
}
Im vorherigen Beispiel wird ein C#-Feld verwendet, um die Quelldaten des Bilds zu aufzunehmen. Für die Aufnahme der Daten können Sie jedoch auch eine C#-Eigenschaft verwenden.
Verwenden Sie die direkte Verwendung einer Schleifenvariablen in einem Lambdaausdruck wie i
im vorangehenden for
-Schleifenbeispiel. Ansonsten wird dieselbe Variable von allen Lambdaausdrücken verwendet, sodass der gleiche Wert in allen Lambdaausdrücken verwendet wird. Erfassen Sie den Wert der Variablen in einer lokalen Variablen. Im vorherigen Beispiel:
- Die Schleifenvariable
i
wirdimageId
zugewiesen. imageId
wird im Lambdaausdruck verwendet.
Verwenden Sie alternativ eine foreach
Schleife mit Enumerable.Range, welche nicht vom vorherigen Problem betroffen ist:
@foreach (var imageId in Enumerable.Range(1, 3))
{
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
Weitere Informationen zu Lambda-Ausdrücken mit Ereignisverarbeitung finden Sie unter ASP.NET Core Blazor Ereignisverarbeitung.
Streamen von Bild- oder Dokumentdaten
Ein Bild oder ein anderes Dokument, wie z. B. eine PDF-Datei, kann mithilfe der Streaming-Interop-Funktionen von Blazor direkt an den Client übertragen werden, anstatt die Datei unter einer öffentlichen URL zu hosten.
Das Beispiel in diesem Abschnitt streamt Quelldaten mithilfe von JavaScript (JS) Interop. Die folgende JS-Funktion setSource
:
- Kann zum Streamen von Inhalten für die folgenden Elemente verwendet werden:
<body>
,<embed>
,<iframe>
,<img>
,<link>
,<object>
,<script>
,<style>
und<track>
. - Akzeptiert das Element
id
, um den Inhalt der Datei, einen Datenstrom für das Dokument, den Inhaltstyp und einen Titel für das Anzeigeelement anzuzeigen.
Mit der Funktion werden folgende Aktionen ausgeführt:
- Sie liest den bereitgestellten Datenstrom in einen
ArrayBuffer
ein. - Erstellt ein
Blob
, um dasArrayBuffer
zu umschließen, und legt den Inhaltstyp des Blobs fest. - Erstellt eine Objekt-URL, die als Adresse für das darzustellende Dokument dient.
- Legt den Titel des Elements (
title
) aus demtitle
-Parameter fest und legt die Quelle des Elements (src
) aus der URL des erstellten Objekts fest. - Um Speicherverluste zu vermeiden, ruft die Funktion
revokeObjectURL
auf, um die Objekt-URL zu entsorgen, nachdem das Element die Ressource geladen hat (load
-Ereignis).
<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>
Hinweis
Allgemeine Anleitungen zu JS Standort und unseren Empfehlungen für Produktions-Apps finden Sie unter JavaScript-Speicherort in ASP.NET Core Blazor -Apps.
Die folgende ShowImage2
-Komponente:
- Fügt Dienste für eine System.Net.Http.HttpClient und Microsoft.JSInterop.IJSRuntime ein.
- Enthält ein
<img>
Tag, um ein Bild anzuzeigen. - Verfügt über eine
GetImageStreamAsync
C#-Methode zum Abrufen einer Stream für ein Bild. Eine Produktions-App kann ein Bild auf der Grundlage des jeweiligen Benutzers dynamisch erzeugen oder ein Bild aus dem Speicher abrufen. Im folgenden Beispiel wird der .NET-Avatar für dasdotnet
GitHub-Repository abgerufen. - Verfügt über eine
SetImageAsync
Methode, die mit der Auswahl der Schaltfläche durch den Benutzer ausgelöst wird.SetImageAsync
führt die folgenden Schritte aus:- Die Methode ruft den Stream aus
GetImageStreamAsync
ab. - Sie umschließt den Stream in einem DotNetStreamReference, der das Streamen der Bilddaten an den Client ermöglicht.
- Ruft die JavaScript-Funktion
setSource
auf, die die Daten auf dem Client entgegennimmt.
- Die Methode ruft den Stream aus
Hinweis
Serverseitige Apps verwenden einen dedizierten HttpClient-Dienst für Anforderungen, sodass keine Aktion von den Entwickelnden einer serverseitigen Blazor-App zum Registrieren eines HttpClient-Diensts erforderlich ist. Clientseitige Apps verfügen über eine HttpClient-Standarddienstregistrierung, wenn die App aus einer Blazor-Projektvorlage erstellt wird. Wenn keine HttpClient-Dienstregistrierung in der Datei Program
einer clientseitigen App vorhanden ist, stellen Sie eine durch Hinzufügen von builder.Services.AddHttpClient();
bereit. Weitere Informationen erhalten Sie unter Stellen von HTTP-Anforderungen mithilfe von 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");
}
}
Die folgende ShowFile
-Komponente lädt entweder eine Textdatei (files/quote.txt
) oder eine PDF-Datei (files/quote.pdf
) in ein <iframe>
-Element (MDN-Dokumentation).
Achtung
Die Verwendung des <iframe>
-Elements im folgenden Beispiel ist sicher und erfordert kein Sandboxing, da der Inhalt aus der App geladen wird, die eine vertrauenswürdige Quelle ist.
Beim Laden von Inhalten aus einer nicht vertrauenswürdigen Quelle oder bei Benutzereingaben besteht bei einem nicht ordnungsgemäß implementierten <iframe>
-Element das Risiko, dass Sicherheitslücken entstehen.
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);
}
}
Zusätzliche Ressourcen
- Blazor-Dateiuploads in ASP.NET Core
- Dateiuploads: Bildvorschau beim Hochladen
- Blazor-Dateidownloads in ASP.NET Core
- Aufrufen von .NET-Methoden über JavaScript-Funktionen in in ASP.NET CoreBlazor
- Aufrufen von JavaScript-Funktionen über .NET-Methoden in in ASP.NET CoreBlazor
- GitHub-Repository mit Blazor-Beispielen (
dotnet/blazor-samples
) (Informationen zum Herunterladen)
ASP.NET Core