ASP.NET Core Blazor 配置

注意

此版本不是本文的最新版本。 有关当前版本,请参阅本文.NET 9 版本。

警告

此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 有关当前版本,请参阅本文.NET 9 版本。

重要

此信息与预发布产品相关,相应产品在商业发布之前可能会进行重大修改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。

有关当前版本,请参阅本文.NET 9 版本。

本文介绍如何配置 Blazor 应用,包括应用设置、身份验证和日志记录配置。

本指南适用于 Blazor Web App 或独立 Blazor WebAssembly 应用中的客户端项目配置。

Blazor Web App 中的默认行为:

  • 对于服务器端配置:
    • 请参阅 ASP.NET Core 中的配置获取相关指导。
    • 仅会加载项目根应用设置文件中的配置。
    • 本文的剩余部分仅适用于 .Client 项目中的客户端配置。
  • 对于客户端配置(.Client 项目),从以下应用设置文件加载配置:
    • wwwroot/appsettings.json
    • wwwroot/appsettings.{ENVIRONMENT}.json,其中 {ENVIRONMENT} 占位符是应用的运行时环境

在独立 Blazor WebAssembly 应用上,从以下应用设置文件加载配置:

  • wwwroot/appsettings.json
  • wwwroot/appsettings.{ENVIRONMENT}.json,其中 {ENVIRONMENT} 占位符是应用的运行时环境

本指导适用于托管 Blazor WebAssembly 解决方案或 Blazor WebAssembly 应用的 Client 项目。

有关托管的 解决方案的 项目中服务器端 ASP.NET Core 应用配置,请参阅 ServerASP.NET Core 中的配置Blazor WebAssembly。

在客户端上,从以下应用设置文件加载配置:

  • wwwroot/appsettings.json
  • wwwroot/appsettings.{ENVIRONMENT}.json,其中 {ENVIRONMENT} 占位符是应用的运行时环境

说明

默认情况下,不会加载放入 wwwroot 中的应用设置文件的日志配置。 有关详细信息,请参阅本文后面的日志记录配置部分。

在某些情况下(例如使用 Azure 服务时),请务必使用与环境名称完全匹配的环境文件名称段。 例如,对于 Staging 环境,将文件名 appsettings.Staging.json 与大写的“S”结合使用。 若要了解推荐的约定,请参阅 ASP.NET Core Blazor 环境的起始描述。

应用注册的其他配置提供程序也可提供配置,但并非所有提供程序或提供程序功能都合适:

  • Azure Key Vault 配置提供程序:在客户端密码方案中,托管的 identity 和应用程序 ID(客户端 ID)不支持该提供程序。 不建议将具有客户端密码的应用程序 ID 用于任何 ASP.NET Core 应用(尤其是客户端侧应用),因为无法在客户端保护客户端密码来访问 Azure Key Vault 服务。
  • Azure 应用程序配置提供程序:该提供程序不适合客户端应用,因为此类应用不在 Azure 中的服务器上运行。

有关配置提供程序的详细信息,请参阅 ASP.NET Core 中的配置

警告

客户端上的用户可以看到位于 Web 根目录(wwwroot 文件夹)中的配置和设置文件,并且用户可以篡改数据。 请勿在任何 Web 根文件中存储应用机密、凭据或任何其他敏感数据。

应用设置配置

会默认加载应用设置文件中的配置。 在下述示例中,UI 配置值存储在应用设置文件中,由 Blazor 框架自动加载。 该值由组件读取。

wwwroot/appsettings.json:

{
    "h1FontSize": "50px"
}

IConfiguration 实例注入到组件中来访问配置数据。

ConfigExample.razor:

@page "/config-example"
@inject IConfiguration Configuration

<PageTitle>Configuration</PageTitle>

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example (50px)
</h1>
@page "/config-example"
@inject IConfiguration Configuration

<PageTitle>Configuration</PageTitle>

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example (50px)
</h1>
@page "/config-example"
@inject IConfiguration Configuration

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example
</h1>
@page "/config-example"
@inject IConfiguration Configuration

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example
</h1>
@page "/config-example"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example
</h1>
@page "/config-example"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example
</h1>

客户端安全限制阻止通过用户代码直接访问文件,包括应用配置的设置文件。 若除了 appsettings.json/appsettings.{ENVIRONMENT}.json 之外,还要将 wwwroot 文件夹中的配置文件读入配置,请使用 HttpClient

警告

客户端上的用户可以看到位于 Web 根目录(wwwroot 文件夹)中的配置和设置文件,并且用户可以篡改数据。 请勿在任何 Web 根文件中存储应用机密、凭据或任何其他敏感数据。

以下示例会将配置文件 (cars.json) 读取到应用的配置中。

wwwroot/cars.json:

{
    "size": "tiny"
}

Microsoft.Extensions.Configuration 的命名空间添加到 Program 文件:

using Microsoft.Extensions.Configuration;

修改现有的 HttpClient 服务注册以使用客户端读取文件:

var http = new HttpClient()
{
    BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
};

builder.Services.AddScoped(sp => http);

using var response = await http.GetAsync("cars.json");
using var stream = await response.Content.ReadAsStreamAsync();

builder.Configuration.AddJsonStream(stream);

前面的示例使用 builder.HostEnvironment.BaseAddress (IWebAssemblyHostEnvironment.BaseAddress) 设置基址,该属性会获取应用的基址,并且通常派生自主机页中 <base> 标记的 href 值。

内存配置源

以下示例使用 Program 文件中的 MemoryConfigurationSource 来提供其他配置。

Microsoft.Extensions.Configuration.Memory 的命名空间添加到 Program 文件:

using Microsoft.Extensions.Configuration.Memory;

Program 文件中:

var vehicleData = new Dictionary<string, string?>()
{
    { "color", "blue" },
    { "type", "car" },
    { "wheels:count", "3" },
    { "wheels:brand", "Blazin" },
    { "wheels:brand:type", "rally" },
    { "wheels:year", "2008" },
};

var memoryConfig = new MemoryConfigurationSource { InitialData = vehicleData };

builder.Configuration.Add(memoryConfig);

IConfiguration 实例注入到组件中来访问配置数据。

MemoryConfig.razor:

@page "/memory-config"
@inject IConfiguration Configuration

<PageTitle>Memory Configuration</PageTitle>

<h1>Memory Configuration Example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>
@page "/memory-config"
@inject IConfiguration Configuration

<PageTitle>Memory Configuration</PageTitle>

<h1>Memory Configuration Example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>
@page "/memory-config"
@inject IConfiguration Configuration

<h1>Memory configuration example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>
@page "/memory-config"
@inject IConfiguration Configuration

<h1>Memory configuration example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>
@page "/memory-config"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1>Memory configuration example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>
@page "/memory-config"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1>Memory configuration example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>

使用 IConfiguration.GetSection 在 C# 代码中获取配置的一部分。 以下示例会获取上一示例中的配置的 wheels 部分:

@code {
    protected override void OnInitialized()
    {
        var wheelsSection = Configuration.GetSection("wheels");

        ...
    }
}

身份验证配置

在应用设置文件中提供公共身份验证配置。

wwwroot/appsettings.json:

{
  "Local": {
    "Authority": "{AUTHORITY}",
    "ClientId": "{CLIENT ID}"
  }
}

使用 Program 文件中的 ConfigurationBinder.Bind 来加载 Identity 提供程序的配置。 以下示例会加载 OIDC 提供程序的配置:

builder.Services.AddOidcAuthentication(options =>
    builder.Configuration.Bind("Local", options.ProviderOptions));

警告

客户端上的用户可以看到位于 Web 根目录(wwwroot 文件夹)中的配置和设置文件,并且用户可以篡改数据。 请勿在任何 Web 根文件中存储应用机密、凭据或任何其他敏感数据。

日志记录配置

本部分适用于通过 wwwroot 文件夹中的应用设置文件配置日志记录的应用。

Microsoft.Extensions.Logging.Configuration 包添加到应用。

注意

有关将包添加到 .NET 应用的指南,请参阅包使用工作流(NuGet 文档)中“安装和管理包”下的文章。 在 NuGet.org 中确认正确的包版本。

在应用设置文件中,提供日志记录配置。 日志记录配置在 Program 文件中加载。

wwwroot/appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

Program 文件中:

builder.Logging.AddConfiguration(
    builder.Configuration.GetSection("Logging"));

主机生成器配置

Program 文件中的 WebAssemblyHostBuilder.Configuration 读取主机生成器配置:

var hostname = builder.Configuration["HostName"];

缓存的配置

配置文件会缓存以供脱机使用。 使用渐进式 Web 应用程序 (PWA) 时,只能在创建新部署时更新配置文件。 在部署之间编辑配置文件不起作用,原因如下:

  • 用户已拥有继续使用的文件的缓存版本。
  • PWA 的 service-worker.jsservice-worker-assets.js 文件必须在编译时重新生成,这会在用户下一次联机访问时通知应用,指示应用已重新部署。

有关 PWA 如何处理后台更新的详细信息,请参阅 ASP.NET Core Blazor 渐进式 Web 应用程序 (PWA)

选项配置

选项配置要求为 Microsoft.Extensions.Options.ConfigurationExtensions NuGet 包添加包引用。

说明

有关将包添加到 .NET 应用的指南,请参阅包使用工作流(NuGet 文档)中“安装和管理包”下的文章。 在 NuGet.org 中确认正确的包版本。

例如:

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

Razor 组件并不支持所有 ASP.NET Core 选项功能。 例如,支持 IOptionsSnapshot<TOptions>IOptionsMonitor<TOptions> 配置,但除了通过在新浏览器选项卡中请求应用或选择浏览器的“重载”按钮重新加载应用之外,不支持重新计算这些接口的选项值。 当基础配置发生更改时,仅调用 StateHasChanged 不会更新快照或监视的选项值。