This is text from a static text file resource.
如果应用中不存在 Properties
文件夹,请在应用的根目录下创建一个 Properties
文件夹。
如果 Properties
文件夹未包含资源文件 (Resources.resx
),请使用“添加”>“新建项”上下文菜单命令在“解决方案资源管理器”中创建文件。
双击 Resource.resx
文件。
从下拉列表中,选择“字符串”>“文件”。
选择“添加资源”>“添加现有文件”。 如果 Visual Studio 提示确认编辑文件,请选择“是”。 导航到 Resources
文件夹,选择 Data.txt
文件,然后选择“打开”。
在以下示例组件中,ResourceManager.GetString 获取字符串资源文本以供显示。
请勿对不受信任的数据采用 ResourceManager 方法。
StaticAssetExample.razor
:
@page "/static-asset-example"
@using System.Resources
<h1>Static Asset Example</h1>
<p>@dataResourceText</p>
@code {
public string dataResourceText = "Loading resource ...";
protected override void OnInitialized()
var resources =
new ResourceManager(typeof(WpfBlazor.Properties.Resources));
dataResourceText = resources.GetString("Data") ?? "'Data' not found.";
将资产放入应用的文件夹(通常位于项目的根目录下)中,例如 Resources
文件夹。 本部分中的示例使用静态文本文件。
Resources/Data.txt
:
This is text from a static text file resource.
在“解决方案资源管理器”中检查与 Form1
关联的文件。 如果 Form1
没有资源文件 (.resx
),请使用“添加”>“新建项”上下文菜单命令添加 Form1.resx
文件。
双击 Form1.resx
文件。
从下拉列表中,选择“字符串”>“文件”。
选择“添加资源”>“添加现有文件”。 如果 Visual Studio 提示确认编辑文件,请选择“是”。 导航到 Resources
文件夹,选择 Data.txt
文件,然后选择“打开”。
在下面的示例组件中:
应用的程序集名称为 WinFormsBlazor
。 将 ResourceManager 的基名称设置为 Form1
的程序集名称 (WinFormsBlazor.Form1
)。
ResourceManager.GetString 获取字符串资源的文本以供显示。
请勿对不受信任的数据采用 ResourceManager 方法。
StaticAssetExample.razor
:
@page "/static-asset-example"
@using System.Resources
<h1>Static Asset Example</h1>
<p>@dataResourceText</p>
@code {
public string dataResourceText = "Loading resource ...";
protected override async Task OnInitializedAsync()
var resources =
new ResourceManager("WinFormsBlazor.Form1", this.GetType().Assembly);
dataResourceText = resources.GetString("Data") ?? "'Data' not found.";
静态资产受限于 Razor 组件
BlazorWebView
控件具有配置的主机文件 (HostPage),通常为 wwwroot/index.html
。 HostPage 路径是项目的相对路径。 从 BlazorWebView
引用的所有静态 Web 资产(脚本、CSS 文件、图像和其他文件)都是其配置的 HostPage 的相对资产。
Razor 类库 (RCL) 中的静态 Web 资产使用特殊路径:_content/{PACKAGE ID}/{PATH AND FILE NAME}
。 {PACKAGE ID}
占位符是库的包 ID。 如果项目文件中没有指定 <PackageId>
,则包 ID 默认为项目的程序集名称。 {PATH AND FILE NAME}
占位符是 wwwroot
下的路径和文件名。 这些路径在逻辑上是应用的 wwwroot
文件夹的子路径,尽管它们实际上来自其他包或项目。 特定于组件的 CSS 样式捆绑包也在 wwwroot
文件夹的根目录中生成。
HostPage 的 Web 根目录决定了哪些静态资产子集可用:
wwwroot/index.html
(推荐):应用 wwwroot
文件夹中的所有资产可用(例如:可从 /image.png
获取 wwwroot/image.png
),包括子文件夹(例如:可从 /subfolder/image.png
获取 wwwroot/subfolder/image.png
)。 RCL 的 wwwroot
文件夹中的 RCL 静态资源可用(例如:可从路径 _content/{PACKAGE ID}/image.png
获得 wwwroot/image.png
),包括子文件夹(例如:可从路径 _content/{PACKAGE ID}/subfolder/image.png
获得 wwwroot/subfolder/image.png
)。
wwwroot/{PATH}/index.html
:应用的 wwwroot/{PATH}
文件夹中的所有资产都可用(使用应用 Web 根相对路径)。 wwwroot/{PATH}
中的 RCL 静态资产不可用,因为它们将位于不存在的理论位置,例如 ../../_content/{PACKAGE ID}/{PATH}
,该位置不是受支持的相对路径。
wwwroot/_content/{PACKAGE ID}/index.html
:RCL 的 wwwroot/{PATH}
文件夹中的所有资产都可用(使用 RCL Web 根相对路径)。 wwwroot/{PATH}
中应用的静态资产不可用,因为它们将位于不存在的理论位置,例如 ../../{PATH}
,该位置不是受支持的相对路径。
对于大多数应用,我们建议将 HostPage 放在应用的 wwwroot
文件夹的根目录中,这样可以最大程度地灵活地从应用、RCL 以及通过应用和 RCL 的子文件夹提供静态资产。
以下示例演示了如何使用来源于 wwwroot
文件夹的 HostPage,从应用的 Web 根目录(wwwroot
文件夹)引用静态资产。
wwwroot/data.txt
:
This is text from a static text file resource.
wwwroot/scripts.js
:
export function showPrompt(message) {
return prompt(message, 'Type anything here');
本部分的示例中还使用了下面的 Jeep® 图像。 可以右键单击以下图像以将其保存在本地,以便在本地测试应用中使用。
wwwroot/jeep-yj.png
:
在 Razor 组件中:
可以使用以下技术读取静态文本文件内容:@page "/static-asset-example-2"
@using Microsoft.Extensions.Logging
@implements IAsyncDisposable
@inject IJSRuntime JS
@inject ILogger<StaticAssetExample2> Logger
<h1>Static Asset Example 2</h1>
<h2>Read a file</h2>
<p>@dataResourceText</p>
<h2>Call JavaScript</h2>
<button @onclick="TriggerPrompt">Trigger browser window prompt</button>
<p>@result</p>
<h2>Show an image</h2>
<p><img alt="1991 Jeep YJ" src="/jeep-yj.png" /></p>
<em>Jeep</em> and <em>Jeep YJ</em> are registered trademarks of
<a href="https://www.stellantis.com">FCA US LLC (Stellantis NV)</a>.
@code {
private string dataResourceText = "Loading resource ...";
private IJSObjectReference? module;
private string result;
protected override async Task OnInitializedAsync()
dataResourceText = await ReadData();
catch (FileNotFoundException ex)
dataResourceText = "Data file not found.";
Logger.LogError(ex, "'wwwroot/data.txt' not found.");
protected override async Task OnAfterRenderAsync(bool firstRender)
if (firstRender)
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./scripts.js");
private async Task TriggerPrompt()
result = await Prompt("Provide some text");
public async ValueTask<string> Prompt(string message) =>
module is not null ?
await module.InvokeAsync<string>("showPrompt", message) : null;
async ValueTask IAsyncDisposable.DisposeAsync()
if (module is not null)
await module.DisposeAsync();
catch (JSDisconnectedException)
在 .NET MAUI 应用中,将以下 ReadData
方法添加到前面组件的 @code
块中:
private async Task<string> ReadData()
using var stream = await FileSystem.OpenAppPackageFileAsync("wwwroot/data.txt");
using var reader = new StreamReader(stream);
return await reader.ReadToEndAsync();
在 WPF 和 Windows 窗体应用中,将以下 ReadData
方法添加到前面组件的 @code
块中:
private async Task<string> ReadData()
using var reader = new StreamReader("wwwroot/data.txt");
return await reader.ReadToEndAsync();
还可在 wwwroot
的逻辑子路径下访问并置的 JavaScript 文件。 不必将前面描述的脚本用于 wwwroot/scripts.js
中的 showPrompt
函数,StaticAssetExample2
组件的以下并置 JavaScript 文件也使该函数可用。
Pages/StaticAssetExample2.razor.js
:
export function showPrompt(message) {
return prompt(message, 'Type anything here');
修改 StaticAssetExample2
组件中的模块对象引用,以使用并置的 JavaScript 文件路径 (./Pages/StaticAssetExample2.razor.js
):
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Pages/StaticAssetExample2.razor.js");
Jeep 和 Jeep YJ 是 FCA 美国有限责任公司 (Stellantis NV) 的注册商标商标。
ResourceManager
为 .NET 应用创建资源文件(.NET 基础知识文档)
如何:使用可本地化的应用中的资源(WPF 文档)