Zobrazení obrázků a dokumentů v ASP.NET Core Blazor
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Tento článek popisuje přístupy k zobrazení obrázků a dokumentů v Blazor aplikacích.
Příklady v tomto článku jsou k dispozici pro kontrolu a použití v ukázkových Blazor aplikacích:
dotnet/blazor-samples
Úložiště GitHub: Přejděte do aplikace s názvem BlazorSample_BlazorWebApp
(8.0 nebo novější), BlazorSample_Server
(7.0 nebo starší) nebo BlazorSample_WebAssembly
.
Dynamické nastavení zdroje obrázku
Následující příklad ukazuje, jak dynamicky nastavit zdroj image s polem C#.
Příklad v této části používá tři soubory obrázků s názvem image1.png
, image2.png
a image3.png
. Obrázky se umístí do složky pojmenované images
ve webovém kořenovém adresáři aplikace (wwwroot
). Použití images
složky je pouze pro demonstrační účely. Statické prostředky můžete uspořádat v libovolném rozložení složky, které preferujete, včetně poskytování prostředků přímo ze wwwroot
složky.
V následující komponentě ShowImage1
:
- Zdroj image (
src
) je dynamicky nastaven na hodnotuimageSource
v jazyce C#. - Metoda
ShowImage
aktualizujeimageSource
pole na základě argumentu obrázkuid
předaného metodě. - Vykreslená tlačítka volají metodu
ShowImage
s argumentem obrázku pro každý ze tří dostupných obrázků veimages
složce. Název souboru se skládá pomocí argumentu předaného metodě a odpovídá jednomu ze tří obrázků veimages
složce.
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";
}
}
Předchozí příklad používá pole jazyka C# k uložení zdrojových dat obrázku, ale k uložení dat můžete použít také vlastnost jazyka C#.
Nepoužívejte proměnnou smyčky přímo ve výrazu lambda, například i
v předchozím příkladu smyčky for
. V opačném případě se stejná proměnná používá ve všech výrazech lambda, což vede k použití stejné hodnoty ve všech výrazech lambda. Zachyťte hodnotu proměnné v místní proměnné. V předchozím příkladu:
- Proměnná
i
smyčky je přiřazena .imageId
imageId
se používá ve výrazu lambda.
Alternativně použijte smyčku foreach
s Enumerable.Range, která netrpí předchozím problémem:
@foreach (var imageId in Enumerable.Range(1, 3))
{
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
}
Další informace o výrazech lambda s zpracováním událostí najdete v tématu ASP.NET zpracování událostí CoreBlazor.
Streamování dat obrázků nebo dokumentů
Obrázek nebo jiný typ dokumentu, například PDF, je možné přímo přenést do klienta pomocí Blazorfunkcí komunikace streamování místo hostování souboru na veřejné adrese URL.
Příklad v této části streamuje zdrojová data pomocí zprostředkovatele komunikace JavaScriptu (JS). setSource
JS Následující funkce:
- Lze použít ke streamování obsahu pro následující prvky: , , , , ,
<link>
,<object>
, ,<script>
,<style>
, a<track>
.<img>
<iframe>
<embed>
<body>
- Přijímá prvek
id
pro zobrazení obsahu souboru, datového proudu pro dokument, typ obsahu a název prvku zobrazení.
Funkce:
- Načte zadaný datový proud do objektu
ArrayBuffer
. Blob
Vytvoří pro zabalení objektuArrayBuffer
blob nastavení typu obsahu objektu blob.- Vytvoří adresu URL objektu, která bude sloužit jako adresa pro zobrazení dokumentu.
- Nastaví název elementu (
title
) z parametrutitle
a nastaví zdroj elementu (src
) z adresy URL vytvořeného objektu. - Aby se zabránilo nevracení paměti, funkce volá
revokeObjectURL
, aby po načtení prvku prostředek (load
událost) zlikvidovaly adresu URL objektu.
<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>
Poznámka:
Obecné pokyny k JS umístění a doporučení pro produkční aplikace najdete v tématu o umístění JavaScriptu v aplikacích ASP.NET CoreBlazor.
ShowImage2
Následující komponenta:
- Vloží služby pro a System.Net.Http.HttpClient Microsoft.JSInterop.IJSRuntime.
<img>
Obsahuje značku pro zobrazení obrázku.- Má metodu jazyka
GetImageStreamAsync
C#, která načte Stream image. Produkční aplikace může dynamicky generovat image na základě konkrétního uživatele nebo načíst image z úložiště. Následující příklad načte avatar .NET prodotnet
úložiště GitHub. - Má metodu
SetImageAsync
, která se aktivuje na výběru tlačítka uživatelem.SetImageAsync
provede následující kroky:- Načte Stream z
GetImageStreamAsync
. - Zabalí do objektu Stream DotNetStreamReference, který umožňuje streamování dat obrázku do klienta.
- Vyvolá javascriptovou
setSource
funkci, která přijímá data v klientovi.
- Načte Stream z
Poznámka:
Aplikace na straně serveru používají k odesílání požadavků vyhrazenou HttpClient službu, takže vývojář aplikace na straně Blazor serveru nevyžaduje žádnou akci k registraci HttpClient služby. Aplikace na straně klienta mají při vytváření aplikace ze Blazor šablony projektu výchozí HttpClient registraci služby. HttpClient Pokud v souboru aplikace na straně klienta není k dispozici Program
registrace služby, zadejte ji přidáním builder.Services.AddHttpClient();
. Další informace najdete v tématu Vytváření požadavků HTTP pomocí IHttpClientFactory v 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");
}
}
Následující ShowFile
komponenta načte textový soubor (files/quote.txt
) nebo pdf soubor (files/quote.pdf
) do elementu <iframe>
(dokumentace k MDN).
Upozornění
Použití elementu <iframe>
v následujícím příkladu je bezpečné a nevyžaduje sandboxing , protože obsah je načten z aplikace, což je důvěryhodný zdroj.
Při načítání obsahu z nedůvěryhodného zdroje nebo vstupu uživatele by nesprávně implementovaný <iframe>
prvek riskoval vytváření ohrožení zabezpečení.
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);
}
}
Další materiály
- nahrávání souborů ASP.NET Core Blazor
- Nahrávání souborů: Nahrání náhledu obrázku
- soubory ASP.NET Core Blazor ke stažení
- Volání metod .NET z funkcí JavaScriptu v ASP.NET Core Blazor
- Volání funkcí JavaScriptu z metod .NET v ASP.NET Core Blazor
- Blazorukázky úložiště GitHub () (
dotnet/blazor-samples
postup stažení)