目录
加载客户端应用程序设置
向客户端公开设置
从客户端获取设置
我通过ASP.NET宠坏了,希望应用程式设置能正常工作,但是客户端Blazor还没有一个容易配置的应用程序设置文章。我想要的是能够通过Azure应用服务应用程序设置在每个环境(dev/test/beta/prod)上设置一些设置。目标是一个构建工件,该工件在环境之间零变化地移动。
如果将Blazor应用程序托管为静态文件,则需要针对每个不同的环境更改应用程序设置文件。因此,我不再使用ASP.NET Core Web Hosted。我已将应用程序命名为AppSettingsExample,因此在解决方案中,我们拥有AppSettingsExample.Client(WASM应用程序),AppSettingsExample.Server(托管应用程序)和AppSettingExample.Shared(客户端与服务器之间共享的代码)
加载客户端应用程序设置我们将通过AppSettingsExample.Server中的内置配置存储和访问客户端应用设置。为此,我们将添加如下appsettings.json值。
{
"ClientAppSettings": {
"BaseApiUrl": "http://somesite.com/api"
}
}
我们还将在AppSettingsExample.Shared项目中创建一个类来保存这些配置。
public class ClientAppSettings
{
public string BaseApiUrl { get; set; }
}
然后,在AppSettingsExample.Server的Startup中,我们将获得对应用程序配置的引用,并将其存储在本地变量中。
private readonly IConfiguration _configuration;
public Startup(IConfiguration configuration)
{
_configuration = configuration;
}
这使我们能够使用配置从appsettings.json中加载设置并将其作为单例添加到依赖项注入配置中。
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(_configuration.GetSection("ClientAppSettings").Get());
向客户端公开设置
没有简单的方法可以将设置传递到客户端Blazor应用程序中,因此我们需要该应用程序从服务器请求它们。我们将创建一个ClientAppSettingsController到AppSettingsExample.Server来提供这些设置。
[Route("api/[controller]")]
[ApiController]
public class ClientAppSettingsController : ControllerBase
{
private readonly ClientAppSettings _clientAppSettings;
public ClientAppSettingsController(ClientAppSettings clientAppSettings)
{
_clientAppSettings = clientAppSettings;
}
[HttpGet]
public ClientAppSettings GetClientAppSettings()
{
return _clientAppSettings;
}
}
从客户端获取设置
这是我最麻烦的地方。在应用程序继续运行之前,我需要完全加载这些设置。如果我异步执行此操作,它将在设置加载完成之前开始在当前页面上运行初始化和ParameterSet方法。如果我试图通过调用.Wait()强制异步Web请求同步完成,则该应用程序将锁定。
为了解决这个问题,我们可以创建一个组件来加载设置,并在加载后显示其子内容。然后,我们可以将内容包装在此组件中,以确保在加载设置之前它不会开始初始化或设置参数。首先,我们创建AppSettingsLoader.razor
@using AppSettingExample.Shared
@inject HttpClient http
@if (IsLoaded)
{
@ChildContent
}
@code
{
[Parameter]
public RenderFragment ChildContent { get; set; }
public bool IsLoaded { get; set; }
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
if (!IsLoaded)
{
var appSettings = await http.GetJsonAsync("api/ClientAppSettings");
AppSettings.BaseApiUrl = appSettings.BaseApiUrl;
IsLoaded = true;
}
}
}
因为我们不能(或无法)将ClientAppSettings实例加载到依赖注入中,以使其在整个应用程序中可用,所以我只是将值放在静态类中。
现在,在MainLayout.razor中我们可以用AppSettingsLoader包装@body
@Body
最后,我们可以在Index.razor页面上引用AppSettings.BaseApiUrl。为了证明这一点,我将其显示在页面上。
@page "/"
Hello, world!
@AppSettings.BaseApiUrl
现在我们可以在AppSettings.json的ClientAppSettings部分设置任何我们喜欢的设置,它将被视为一个普通的应用设置,包括能够通过Azure应用服务的配置部分设置设置。