第二章 基础知识(2) - 配置

注意
客户端上的用户可以看到配置和设置文件,用户可以篡改数据。 请勿在应用的配置或文件中存储应用机密、凭据或任何其他敏感数据。
使用交互式 WebAssembly 或交互式自动渲染模式时,请记住所有组件代码都会编译并发送到客户端,用户可以在客户端对其进行反向编译和检查。 请勿在客户端渲染的组件中放置专用代码、应用机密或其他敏感信息。

应用参数配置

一、文件配置源

1、项目默认配置文件

这里以Blazor web app Auto/Per page项目为例子,创建项目后,可以看到解决方案中会出现两个项目,一个是服务端,一个是客户端(.Client)。这两个项目中,都存在默认项目配置文件appsettings.jsonappsettings.Development.json
配置文件的加载规则
既然存在两个默认配置文件,那么当应用运行时,具体是用哪一个配置文件中的数据呢?
首相,在生产环境下,也就是进行了发布、托管部署后,是直接使用各自项目中的appsettings.json文件的。
如果是在调试环境下(VS中),appsettings.json是必定加载的,至于appsettings.Development.json加载还是不加载,要看一下launchSettings.json文件中,运行服务的配置。如果选择的运行服务环境配置为Development那么会把appsettings.Development.json也加载进来,反之则不加载。
默认情况下,在本地运行应用时,环境默认为 Development。 发布应用时,环境默认为 Production
在这里插入图片描述 在这里插入图片描述

加载配置文件后,就可以直接使用IConfiguration服务来直接获取。
如果两个配置文件都加载了,则会先到appsettings.Development.json中寻找对应参数,如果没有,再到appsettings.json中查找。
作用区域
如果是在服务端的项目配置文件中配置了参数,那么当组件进行预渲染或服务端交互渲染时,可以读取到,当组件客户端交互渲染时则无法读取。
如果是在客户端的项目配置文件中配置了参数,那么当组件进行预渲染或服务端交互渲染时,读取不到,当组件进行客户端交互渲染时可以读取到。
例如,在服务端的appsettings.json文件中,添加如下参数:

{
   "Logging": {
     "LogLevel": {
       "Default": "Information",
       "Microsoft.AspNetCore": "Warning"
     }
   },
   "AllowedHosts": "*",
   "MyData": "TestData"
}

然后在客户端项目中,添加Auto渲染模式的组件:

ConfigTest.razor

@page "/config-test"
@rendermode InteractiveAuto
@inject IConfiguration Configuration

<h3>ConfigTest</h3>

<p>
    @if (@Configuration["MyData"] is object)
    {
        @:预渲染或服务端交互渲染,读取到参数 MyData:@Configuration["MyData"]
    }
    else
    {
        @:客户端交互渲染,无法读取到参数
    }
</p>

例子中,使用了Auto渲染模式,一开始会进行预渲染、服务端交互渲染,然后会进行客户端交互渲染,所以只有刚开始出现页面时能访问到数据,过一会切换到客户端交互渲染后,就访问不到了。

2、静态资源配置文件

上面的所使用的是项目的默认json配置文件,一般情况下,项目配置文件多用来进行一些较为关键的参数配置,例如日志、数据库连接字符串等等。如果有额外的参数需要配置,建议在wwwroot文件夹下,创建新的json配置文件,进行参数的配置。

newDataConfig.json

{
  "MyData1": "DataTest1",
  "MyData2": {
    "Name": "Schuyler",
    "Age": 23
  },
  "MyData3": [
    {
      "Name": "Schuyler1",
      "Age": 24
    },
    {
      "Name": "Schuyler2",
      "Age": 25
    }
  ]
}

在这里插入图片描述
客户端安全限制阻止通过用户代码直接访问文件,包括配置文件。 若除了appsettings.json/appsettings.Development.json 之外,还要将 wwwroot 文件夹中的配置文件加载到IConfiguration服务中,则需要使用HttpClient来进行文件的访问。

  • 注意,以客户端为例,除了appsettings.json/appsettings.Development.json会自动加载外,不管是想使用自己项目中的wwwroot文件夹下的配置文件还是服务端项目中的wwwroot文件夹下的配置文件,最好都用HttpClient来进行加载。

示例-客户端项目的Program.cs

var builder = WebAssemblyHostBuilder.CreateDefault(args);

var http = new HttpClient()
{
    BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
};
builder.Services.AddScoped(sp => http);
using var response = await http.GetAsync("newDataConfig2.json");
using var stream = await response.Content.ReadAsStreamAsync();
builder.Configuration.AddJsonStream(stream);

await builder.Build().RunAsync();

二、内存配置源

除了使用文件进行配置外,还可以在Program中,使用内存来进行参数配置。

Program.cs

var builder = WebAssemblyHostBuilder.CreateDefault(args);
//内存参数配置
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);

await builder.Build().RunAsync();

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

ConfigTest.razor

@page "/config-test"
@rendermode InteractiveAuto
@inject IConfiguration Configuration

<h3>ConfigTest</h3>

<p>
    @if (@Configuration["color"] is object)
    {
        @:读取到参数 color:@Configuration["color"]
    }
    else
    {
        @:无法读取到参数
    }
</p>

启动

一、启动过程和配置

1、自动启动

Blazor 启动过程默认情况下,是通过 Blazor 内置的JS脚本 (例如blazor.web.jsblazor.server.jsblazor.webassembly.js等) 自动异步完成的,不同托管方式的Blazor脚本的引入位置如下(后面一律称为 Blazor<script> 标记):

  • Blazor Web 应用,Blazor 脚本位于 Components/App.razor 文件中
    <script src="_framework/blazor.web.js"></script>
    
  • Blazor Server 应用,Blazor 脚本位于 Pages/_Host.cshtml 文件中
    <script src="_framework/blazor.server.js"></script>
    
  • Blazor WebAssembly 应用,Blazor 脚本内容位于 wwwroot/index.html 文件中
    <script src="_framework/blazor.webassembly.js"></script>
    

后面的关于不同应用的内置启动JS脚本的路径,都用{BLAZOR SCRIPT}进行表示了,不然太冗余。

2、手动启动

有时候需要在Blazor启动时,做一些自定义的初始化操作,Blazor Web App可以通过如下步骤来实现:

  • autostart="false" 属性和值添加到 Blazor<script> 标记中
  • 将调用 Blazor.start() 的Js脚本放置在 Blazor启动脚本的</script> 标记之后并放在结束的 </body> 标记内。
  • 将静态服务器端渲染(静态 SSR)选项置于 ssr 属性中。(如果需要设置)
  • 将服务器端 Blazor-SignalR 线路选项置于 circuit 属性中。(如果需要设置)
  • 将客户端 WebAssembly 选项置于 webAssembly 属性中。(如果需要设置)

示例

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  ...
  Blazor.start({
    ssr: {
      ...
    },
    circuit: {
      ...
    },
    webAssembly: {
      ...
    }
  });
  //如果不需要进行设置,那么直接Start
  //Blazor.start();
  ...
</script>

当然了,如果是单独的Blazor Server或者是Blazor WebAssembly只需要设置自己对应的选项就好。
手动启动后执行JS代码
如果希望再Blazor启动后执行一些JS任务,可以链式调用then()方法。

  • 建议使用JS 初始值设定项(详看下文),而不是then()

示例

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start().then(function () {
    ...
  });
</script>

文档准备就绪后再初始化 Blazor

示例

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  document.addEventListener("DOMContentLoaded", function() {
    Blazor.start();
  });
</script>

二、JavaScript 初始值设定项

JavaScript 初始值设定项在 Blazor 应用加载之前或之后执行逻辑。 JS 初始值设定项在以下场景中很有用:

  • 自定义 Blazor 应用的加载方式。
  • 在 Blazor 启动之前初始化库。
  • 配置 Blazor 设置。

JS 初始值设定项是在生成过程中检测并自动进行导入的,不需要再去手动触发脚本。如果要定义 JS 初始值设定项,需要在项目的根目录中,默认情况下即 wwwroot 文件夹下,添加{NAME}.lib.module.js文件,其中{NAME}占位符表示当前程序集名称。
在这里插入图片描述

1、初始化回调方法

Blazor Web 应用

  • beforeWebStart(options):在 Blazor Web 应用启动之前调用,用于自定义加载过程、日志记录级别和其他选项。 Blazor Web 选项对象作为options参数传递给beforeWebStart
  • afterWebStarted(blazor):在所有 beforeWebStart 解决后调用,可用于注册 Blazor 事件侦听器和自定义事件类型。 Blazor 实例作为参数blazor传递给 afterWebStarted
  • beforeServerStart(options, extensions):在启动第一个服务器运行时之前调用。 接收 SignalR 路线启动选项 (options) 以及在发布期间添加的任何扩展 (extensions)。
  • afterServerStarted(blazor):在启动第一个交互式服务器运行时之后调用。
  • beforeWebAssemblyStart(options, extensions):在启动交互式 WebAssembly 运行时之前调用。 接收 Blazor 选项 (options) 以及在发布期间添加的任何扩展 (extensions)。选项可以指定使用自定义启动资源加载程序。
  • afterWebAssemblyStarted(blazor):在启动交互式 WebAssembly 运行时之后调用。

Blazor Server、Blazor WebAssembly 和 Blazor Hybrid 应用

  • beforeStart(options, extensions):在 Blazor 启动之前调用。用于自定义加载过程、日志记录级别以及其他特定于托管模型的选项。
  • afterStarted(blazor):在 Blazor 准备好从 JS 接收调用后调用。 用于通过进行 JS 互操作调用并注册自定义元素来初始化库。 Blazor 实例作为参数blazor传递给 afterStarted

2、导入其他模块

如果要在JS初始值设定项中使用其他JS文件,可以通过import语句导入

additionalModule.js

export function logMessage() {
  console.log('logMessage is logging');
}

{NAME}.lib.module.js

import { logMessage } from "/additionalModule.js";

export function beforeStart(options, extensions) {
  ...

  logMessage();
}

3、示例

确保加载JS库的顺序

以下示例在 script2.js 之前加载 script1.js,在 script4.js 之前加载 script3.js

export function beforeWebStart(options, extensions) {
    var customScript1 = document.createElement('script');
    customScript1.setAttribute('src', 'script1.js');
    document.head.appendChild(customScript1);

    var customScript2 = document.createElement('script');
    customScript2.setAttribute('src', 'script2.js');
    document.head.appendChild(customScript2);
}

export function afterWebStarted(blazor) {
    var customScript1 = document.createElement('script');
    customScript1.setAttribute('src', 'script3.js');
    document.head.appendChild(customScript1);

    var customScript2 = document.createElement('script');
    customScript2.setAttribute('src', 'script4.js');
    document.head.appendChild(customScript2);
}

环境

在本地运行应用时,环境默认为 Development。 发布应用时,环境默认为 Production
建议使用以下约定

  • 始终使用Development环境名称进行本地开发。 这是因为,在为应用的本地开发运行配置应用和工具时,ASP.NET Core 框架确切需要该名称。
  • 对于测试、暂存和生产环境,请始终发布和部署应用。 可以使用希望用于已发布应用的任何环境命名方案,但始终使用应用设置文件名,环境段的大小写应与环境名称完全匹配。 对于暂存,请使用“Staging”(大写“S”)作为环境名称,并命名要匹配的应用设置文件 (appsettings.Staging.json)。 对于生产,请使用“Production”(大写“P”)作为环境名称,并命名要匹配的应用设置文件 (appsettings.Production.json)。

一、组件中读取环境

在客户端组件中,如果想要获取应用的环境信息,可以通过注入IWebAssemblyHostEnvironment 并读取 Environment 属性来得到。

@page "/read-environment"
@using Microsoft.AspNetCore.Components.WebAssembly.Hosting
@inject IWebAssemblyHostEnvironment Env

<h1>Environment example</h1>

<p>Environment: @HostEnvironment.Environment</p>

需要注意的是,对于Blazor Web App Auto应用,IWebAssemblyHostEnvironment仅在客户端项目(.Client)中进行了服务的注册,如果客户端项目中的组件允许预渲染,那么当组件在服务器上预渲染时,会由于找不到IWebAssemblyHostEnvironment而在注入该服务时出现异常。
针对这个问题,可以在服务器项目上创建IWebAssemblyHostEnvironment的自定义服务,然后进行注册:

ServerHostEnvironment.cs

public class ServerHostEnvironment(IWebHostEnvironment env, NavigationManager nav) : IWebAssemblyHostEnvironment
{
    public string Environment => env.EnvironmentName;
    public string BaseAddress => nav.BaseUri;
}

Program.cs

......
builder.Services.TryAddScoped<IWebAssemblyHostEnvironment, ServerHostEnvironment>();
......

二、启动时读取客户端环境

在启动过程中,WebAssemblyHostBuilder会通过HostEnvironment属性公开 IWebAssemblyHostEnvironment,因此可以在客户端项目的Program中,通过builder.HostEnvironment来获取环境信息。

if (builder.HostEnvironment.Environment == "Development")
{
    ...
};

类似HostEnvironmentEnvExtensionsIHostEnvironment(服务端项目中Program.cs所使用的主机环境类型)提供了一系列便捷的扩展方法一样,WebAssemblyHostEnvironmentExtensions则是为IWebAssemblyHostEnvironment(客户端项目中Program.cs所使用的主机环境类型)提供了一系列便捷的扩展方法,可在当前环境中检查 DevelopmentProductionStaging 和自定义环境名称

  • bool IsDevelopment()
  • bool IsProduction()
  • bool IsStaging()
  • bool IsEnvironment(envName)
if (builder.HostEnvironment.IsStaging())
{
    ...
};

if (builder.HostEnvironment.IsEnvironment("Custom"))
{
    ...
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SchuylerEX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值