本文介绍在 Blazor 应用中显示图像和文档的方法。
本文中的示例可在
Blazor 示例应用
中查看和使用:
dotnet/blazor-samples
GitHub 存储库
:导航到名为
BlazorSample_BlazorWebApp
(8.0 或更高版本)、
BlazorSample_Server
(7.0 或更早版本)或
BlazorSample_WebAssembly
的应用。
动态设置图像源
下面的示例演示如何使用 C# 字段动态设置图像的源。
本节中的示例使用三个图像文件,分别名为
image1.png
、
image2.png
和
image3.png
。 图像放置在应用的 Web 根目录 (
wwwroot
) 中名为
images
的文件夹中。
images
文件夹的使用仅用于演示目的。 可以按照你喜欢的任何文件夹布局来组织图像资产,包括直接从
wwwroot
文件夹提供图像。
在下面的
ShowImage1
组件中:
图像中的源 (
src
) 动态设置为 C# 中的值
imageSource
。
ShowImage
方法基于传递到方法的图像
id
参数更新
imageSource
字段。
呈现的按钮使用
images
文件夹中每个可用图像(共三个)的图像参数调用
ShowImage
方法。 文件名使用传递给该方法的参数组成,并匹配
images
文件夹中的三个图像之一。
ShowImage1.razor
:
@page "/show-image-1"
<PageTitle>Show Image 1</PageTitle>
<h1>Show Image Example 1</h1>
@if (imageSource is not null)
<img src="@imageSource" />
@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)
<img src="@imageSource" />
@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)
<img src="@imageSource" />
@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)
<img src="@imageSource" />
@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";
前面的示例使用 C# 字段来保存图像的源数据,但也可使用 C# 属性来保存数据。
避免直接在 Lambda 表达式中使用循环变量,如前面的 for
循环示例中的 i
。 否则,所有 Lambda 表达式将使用相同的变量,这将导致在所有 Lambda 中使用相同的值。 在局部变量中捕获该变量的值。 在上面的示例中:
将循环变量 i
分配到 imageId
。
将 imageId
用于 lambda 表达式。
或者,将 foreach
循环与 Enumerable.Range 结合使用,这样就能避开上述问题:
@foreach (var imageId in Enumerable.Range(1, 3))
<button @onclick="() => ShowImage(imageId)">
Image @imageId
</button>
有关 lambda 表达式和事件处理的详细信息,请参阅 ASP.NET Core Blazor 事件处理。
流式传输图像或文档数据
可以使用 Blazor 的流式互操作功能将图像或其他文档类型(例如 PDF)直接传输到客户端,而不是将文件托管在公共 URL 上。
本部分中的示例使用 JavaScript (JS) 互操作流式传输源数据。 以下 setSource
JS 函数:
可用于流式传输以下元素的内容:<body>
、<embed>
、<iframe>
、<img>
、<link>
、<object>
、<script>
、<style>
和<track>
。
接受用于显示文件内容的元素 id
、文档的数据流、内容类型以及显示元素的标题。
将提供的流读入 ArrayBuffer
。
创建一个 Blob
来包装 ArrayBuffer
,并设置 Blob 的内容类型。
创建一个对象 URL,作为要显示的文档的地址。
从 title
参数设置元素的标题 (title
),并从创建的对象 URL 设置元素的源 (src
)。
为了防止内存泄漏,函数会在元素加载资源(load
事件)后调用 revokeObjectURL
来处理对象 URL。
<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>
有关 JS 的常规指导和我们对常规应用的建议,请参阅 ASP.NET Core Blazor 应用中的 JavaScript 位置。
以下 ShowImage2
组件:
为 System.Net.Http.HttpClient 和 Microsoft.JSInterop.IJSRuntime 注入服务。
包含用于显示图像的标记 <img>
。
拥有用于检索图像的 Stream 的 GetImageStreamAsync
C# 方法。 生产应用可以基于特定用户动态生成图像,或者从存储中检索图像。 以下示例检索 dotnet
GitHub 存储库的 .NET 头像。
拥有在用户选择按钮时触发的 SetImageAsync
方法。 SetImageAsync
执行下列步骤:@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" />
@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" />
@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" />
@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" />
@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");
以下 ShowFile
组件可将文本文件 (files/quote.txt
) 或 PDF 文件 (files/quote.pdf
) 加载到 <iframe>
元素(MDN 文档)。
在以下示例中使用 <iframe>
元素是安全的,不需要沙盒,因为内容是从应用(受信任的源)加载的。
从不受信任的源或用户输入加载内容时,未正确地实现 <iframe>
元素可能会导致安全漏洞。
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>
<iframe id="iframe" style="height: calc(100vh - 200px)" />
@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>
<iframe id="iframe" style="height: calc(100vh - 200px)" />
@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>
<iframe id="iframe" style="height: calc(100vh - 200px)" />
@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>
<iframe id="iframe" style="height: calc(100vh - 200px)" />
@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);
ASP.NET Core Blazor 文件上传
文件上传:上传图像预览
ASP.NET Core Blazor 文件下载
在 ASP.NET Core Blazor 中从 JavaScript 函数调用 .NET 方法
在 ASP.NET Core Blazor 中从 .NET 方法调用 JavaScript 函数
Blazor 示例 GitHub 存储库 (dotnet/blazor-samples
)(下载方法)