Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu dla .NET 9.
Ostrzeżenie
Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu dla .NET 9.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu dla .NET 9.
W tym artykule opisano metody wyświetlania obrazów i dokumentów w Blazor aplikacjach.
Przykłady w tym artykule są dostępne do inspekcji i użycia w przykładowych Blazor aplikacjach:
dotnet/blazor-samples
Repozytorium GitHub: przejdź do aplikacji o nazwie BlazorSample_BlazorWebApp
(8.0 lub nowszej), BlazorSample_Server
(7.0 lub starszej) lub BlazorSample_WebAssembly
.
Dynamiczne ustawianie źródła obrazu
W poniższym przykładzie pokazano, jak dynamicznie ustawić źródło obrazu przy użyciu pola języka C#.
W przykładzie w tej sekcji użyto trzech plików obrazów o nazwie image1.png
, image2.png
i image3.png
. Obrazy są umieszczane w folderze o nazwie images
w katalogu głównym aplikacji (wwwroot
). Korzystanie z images
folderu jest przeznaczone tylko do celów demonstracyjnych. Zasoby statyczne można organizować w dowolnym układzie folderów według własnych upodobań, łącznie z możliwością obsługi zasobów bezpośrednio z folderu wwwroot
.
W poniższym składniku ShowImage1
:
- Źródło obrazu (
src
) jest dynamicznie ustawiane na wartośćimageSource
w języku C#. - Metoda
ShowImage
aktualizujeimageSource
pole na podstawie argumentu obrazuid
przekazanego do metody . - Renderowane przyciski wywołują metodę
ShowImage
z argumentem obrazu dla każdej z trzech dostępnych grafik w folderzeimages
. Nazwa pliku składa się przy użyciu argumentu przekazanego do metody i pasuje do jednego z trzech obrazów w folderzeimages
.
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";
}
}
W poprzednim przykładzie do przechowywania danych źródłowych obrazu jest używane pole języka C#, ale do przechowywania danych można również użyć właściwości języka C#.
Unikaj używania zmiennej pętli bezpośrednio w wyrażeniu lambda, takim jak i
w poprzednim przykładzie for
pętli. W przeciwnym razie ta sama zmienna jest używana przez wszystkie wyrażenia lambda, co powoduje użycie tej samej wartości we wszystkich wyrażeniach lambda. Uchwyć wartość zmiennej w zmiennej lokalnej. W powyższym przykładzie:
- Zmienna sterująca pętli
i
jest przypisywana doimageId
. -
imageId
jest używany w wyrażeniu lambda.
Można użyć foreach
pętli z Enumerable.Range, która nie ma problemu występującego wcześniej.
@foreach (var imageId in Enumerable.Range(1, 3))
{
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
Aby uzyskać więcej informacji na temat wyrażeń lambda z obsługą zdarzeń, zobacz Blazor ASP.NET Core.
Przesyłanie strumieniowe danych obrazu lub dokumentu
Obraz lub inny typ dokumentu, taki jak PDF, można przesyłać bezpośrednio do klienta przy użyciu Blazor funkcji przesyłania strumieniowego zamiast umieszczania pliku pod publicznym adresem URL.
Przykład w tej sekcji przesyła strumieniowo dane źródłowe przy użyciu JS języka JavaScript (). Następująca setSource
JS funkcja:
- Może służyć do przesyłania strumieniowego zawartości dla następujących elementów:
<body>
,<embed>
,<iframe>
,<img>
,<link>
,<object>
,<script>
,<style>
i<track>
. - Akceptuje element
id
do wyświetlania zawartości pliku, strumienia danych dokumentu, typu zawartości i tytułu elementu wyświetlania.
Funkcja:
- Odczytuje dostarczony strumień do elementu
ArrayBuffer
. - Tworzy
Blob
do opakowaniaArrayBuffer
, ustawiając typ zawartości obiektu blob. - Tworzy adres URL obiektu, który będzie służył jako adres dokumentu do wyświetlenia.
- Ustaw tytuł elementu (
title
) z parametrutitle
i ustawia źródło elementu (src
) na podstawie utworzonego adresu URL obiektu. - Aby zapobiec wyciekom pamięci, funkcja wywołuje
revokeObjectURL
w celu zamknięcia adresu URL obiektu po załadowaniu zasobu (load
wydarzenie).
<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>
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Blazor ASP.NET Core.
ShowImage2
Następujący składnik:
- Wprowadza usługi dla komponentu System.Net.Http.HttpClient i Microsoft.JSInterop.IJSRuntime.
-
<img>
Zawiera tag do wyświetlenia obrazu. - Ma metodę C#
GetImageStreamAsync
, aby pobrać Stream dla obrazu. Aplikacja produkcyjna może dynamicznie generować obraz na podstawie określonego użytkownika lub pobierać obraz z magazynu. Poniższy przykład pobiera obrazek awatara dla platformy .NET dodotnet
repozytorium GitHub. - Ma metodę
SetImageAsync
wyzwalaną przez użytkownika po wybraniu przycisku.SetImageAsync
wykonuje następujące kroki:- Pobiera element Stream z
GetImageStreamAsync
. - Opakowuje element Stream w element DotNetStreamReference, co umożliwia strumieniowanie danych obrazu do klienta.
-
setSource
Wywołuje funkcję JavaScript, która akceptuje dane na kliencie.
- Pobiera element Stream z
Uwaga
Aplikacje po stronie serwera używają dedykowanej HttpClient usługi do tworzenia żądań, więc deweloper aplikacji po stronie Blazor serwera nie musi wykonywać żadnych działań w celu zarejestrowania HttpClient usługi. Aplikacje po stronie klienta mają domyślną HttpClient rejestrację usługi podczas tworzenia aplikacji na podstawie Blazor szablonu projektu.
HttpClient Jeśli rejestracja usługi nie istnieje w Program
pliku aplikacji po stronie klienta, należy ją dodać, dodając builder.Services.AddHttpClient();
. Aby uzyskać więcej informacji, zobacz Tworzenie żądań HTTP za pomocą interfejsu IHttpClientFactory na platformie 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");
}
}
Poniższy składnik ShowFile
ładuje plik tekstowy (files/quote.txt
) lub plik PDF (files/quote.pdf
) do elementu <iframe>
.
Ostrzeżenie
Użycie elementu <iframe>
w poniższym przykładzie jest bezpieczne i nie wymaga kontroli w izolowanym środowisku, ponieważ zawartość jest ładowana z aplikacji, która jest zaufanym źródłem.
Podczas ładowania zawartości z niezaufanego źródła lub danych wejściowych użytkownika nieprawidłowo zaimplementowany <iframe>
element stanowi zagrożenie związane z tworzeniem luk w zabezpieczeniach.
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}");
using 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}");
using 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}");
using 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}");
using 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);
}
}
Dodatkowe zasoby
- przekazywanie plików ASP.NET Core Blazor
- Przekazywanie plików: przekazywanie podglądu obrazu
- pobieranie plików ASP.NET Core Blazor
- Wywoływanie metod platformy .NET z funkcji języka JavaScript z na platformie ASP.NET Core Blazor
- Wywoływanie funkcji języka JavaScript z metod platformy .NET na platformie ASP.NET Core Blazor
-
Blazor (
dotnet/blazor-samples
jak pobrać)