Menampilkan gambar dan dokumen di ASP.NET Core Blazor
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Artikel ini menjelaskan pendekatan untuk menampilkan gambar dan dokumen di Blazor aplikasi.
Contoh dalam artikel ini tersedia untuk diperiksa dan digunakan dalam Blazor aplikasi sampel:
dotnet/blazor-samples
Repositori GitHub: Navigasikan ke aplikasi bernama BlazorSample_BlazorWebApp
(8.0 atau yang lebih baru), BlazorSample_Server
(7.0 atau yang lebih lama), atau BlazorSample_WebAssembly
.
Mengatur sumber gambar secara dinamis
Contoh berikut menunjukkan cara mengatur sumber gambar secara dinamis dengan bidang C#.
Contoh di bagian ini menggunakan tiga file gambar, bernama image1.png
, image2.png
, dan image3.png
. Gambar ditempatkan dalam folder bernama images
di akar web aplikasi (wwwroot
). Penggunaan images
folder hanya untuk tujuan demonstrasi. Anda dapat mengatur aset statis dalam tata letak folder apa pun yang Anda sukai, termasuk menyajikan aset langsung dari wwwroot
folder.
Dalam komponen ShowImage1
berikut:
- Sumber gambar (
src
) secara dinamis diatur ke nilaiimageSource
dalam C#. - Metode
ShowImage
memperbaruiimageSource
bidang berdasarkan argumen gambarid
yang diteruskan ke metode . - Tombol yang dirender memanggil
ShowImage
metode dengan argumen gambar untuk masing-masing dari tiga gambar yangimages
tersedia di folder. Nama file terdiri menggunakan argumen yang diteruskan ke metode dan cocok dengan salah satu dari tiga gambar dalamimages
folder.
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";
}
}
Contoh sebelumnya menggunakan bidang C# untuk menyimpan data sumber gambar, tetapi Anda juga dapat menggunakan properti C# untuk menyimpan data.
Hindari menggunakan variabel loop langsung dalam ekspresi lambda, seperti i
dalam contoh perulangan sebelumnya for
. Jika tidak, variabel yang sama digunakan oleh semua ekspresi lambda, yang menghasilkan penggunaan nilai yang sama di semua lambda. Ambil nilai variabel dalam variabel lokal. Dalam contoh sebelumnya:
- Variabel
i
perulangan ditetapkan keimageId
. imageId
digunakan dalam ekspresi lambda.
Atau, gunakan perulangan foreach
dengan Enumerable.Range, yang tidak menderita masalah sebelumnya:
@foreach (var imageId in Enumerable.Range(1, 3))
{
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
Untuk informasi selengkapnya tentang ekspresi lambda dengan penanganan peristiwa, lihat penanganan peristiwa ASP.NET CoreBlazor.
Mengalirkan data gambar atau dokumen
Gambar atau jenis dokumen lainnya, seperti PDF, dapat langsung ditransmisikan ke klien menggunakan Blazorfitur interop streaming alih-alih menghosting file di URL publik.
Contoh di bagian ini mengalirkan data sumber menggunakan interop JavaScript (JS). Fungsi berikut setSource
JS :
- Dapat digunakan untuk mengalirkan konten untuk elemen berikut:
<body>
, , ,<embed>
<iframe>
,<img>
<link>
,<object>
,<script>
, ,<style>
, dan<track>
. - Menerima elemen
id
untuk menampilkan konten file, aliran data untuk dokumen, jenis konten, dan judul untuk elemen tampilan.
Fungsi :
- Membaca aliran yang disediakan ke dalam
ArrayBuffer
. - Membuat untuk membungkus
Blob
ArrayBuffer
, mengatur jenis konten blob. - Membuat URL objek untuk berfungsi sebagai alamat dokumen yang akan ditampilkan.
- Atur judul elemen (
title
) darititle
parameter dan mengatur sumber elemen (src
) dari URL objek yang dibuat. - Untuk mencegah kebocoran memori, fungsi memanggil
revokeObjectURL
untuk membuang URL objek setelah elemen memuat sumber daya (load
peristiwa).
<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>
Catatan
Untuk panduan umum tentang JS lokasi dan rekomendasi kami untuk aplikasi produksi, lihat Lokasi JavaScript di aplikasi ASP.NET CoreBlazor.
Komponen berikut ShowImage2
:
- Menyuntikkan layanan untuk dan System.Net.Http.HttpClient Microsoft.JSInterop.IJSRuntime.
<img>
Menyertakan tag untuk menampilkan gambar.- Memiliki
GetImageStreamAsync
metode C# untuk mengambil Stream gambar. Aplikasi produksi dapat secara dinamis menghasilkan gambar berdasarkan pengguna tertentu atau mengambil gambar dari penyimpanan. Contoh berikut mengambil avatar .NET untukdotnet
repositori GitHub. - Memiliki
SetImageAsync
metode yang dipicu pada pilihan tombol oleh pengguna.SetImageAsync
lakukan langkah-langkah berikut:- Mengambil Stream dari
GetImageStreamAsync
. - Membungkus Stream dalam DotNetStreamReference, yang memungkinkan streaming data gambar ke klien.
- Memanggil
setSource
fungsi JavaScript, yang menerima data pada klien.
- Mengambil Stream dari
Catatan
Aplikasi sisi server menggunakan layanan khusus HttpClient untuk membuat permintaan, sehingga tidak ada tindakan yang diperlukan oleh pengembang aplikasi sisi Blazor server untuk mendaftarkan HttpClient layanan. Aplikasi sisi klien memiliki pendaftaran layanan default HttpClient saat aplikasi dibuat dari Blazor templat proyek. HttpClient Jika pendaftaran layanan tidak ada dalam Program
file aplikasi sisi klien, berikan dengan menambahkan builder.Services.AddHttpClient();
. Untuk informasi lebih lanjut, lihat Membuat permintaan HTTP menggunakan IHttpClientFactory di 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");
}
}
Komponen berikut ShowFile
memuat file teks (files/quote.txt
) atau file PDF (files/quote.pdf
) ke dalam <iframe>
elemen (dokumentasi MDN).
Perhatian
Penggunaan <iframe>
elemen dalam contoh berikut aman dan tidak memerlukan kotak pasir karena konten dimuat dari aplikasi, yang merupakan sumber tepercaya.
Saat memuat konten dari sumber atau input pengguna yang tidak tepercaya, elemen yang diimplementasikan <iframe>
dengan tidak benar berisiko menciptakan kerentanan keamanan.
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);
}
}
Sumber Daya Tambahan:
- unggahan file ASP.NET Core Blazor
- Unggahan file: Mengunggah pratinjau gambar
- unduhan file ASP.NET Core Blazor
- Memanggil metode .NET dari fungsi JavaScript di Blazor ASP.NET Core
- Memanggil fungsi JavaScript dari metode .NET di Blazor ASP.NET Core
- Blazorsampel repositori GitHub () (
dotnet/blazor-samples
cara mengunduh)
ASP.NET Core