客户端Blazor中的应用程序设置

目录

加载客户端应用程序设置

向客户端公开设置

从客户端获取设置


我通过ASP.NET宠坏了,希望应用程式设置能正常工作,但是客户端Blazor还没有一个容易配置的应用程序设置文章。我想要的是能够通过Azure应用服务应用程序设置在每个环境(dev/test/beta/prod)上设置一些设置。目标是一个构建工件,该工件在环境之间零变化地移动。

如果将Blazor应用程序托管为静态文件,则需要针对每个不同的环境更改应用程序设置文件。因此,我不再使用ASP.NET Core Web Hosted。我已将应用程序命名为AppSettingsExample,因此在解决方案中,我们拥有AppSettingsExample.ClientWASM应用程序),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.ServerStartup中,我们将获得对应用程序配置的引用,并将其存储在本地变量中。

private readonly IConfiguration _configuration;

public Startup(IConfiguration configuration)
{
    _configuration = configuration;
}

这使我们能够使用配置从appsettings.json中加载设置并将其作为单例添加到依赖项注入配置中。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton(_configuration.GetSection("ClientAppSettings").Get<ClientAppSettings>());

向客户端公开设置

没有简单的方法可以将设置传递到客户端Blazor应用程序中,因此我们需要该应用程序从服务器请求它们。我们将创建一个ClientAppSettingsControllerAppSettingsExample.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<ClientAppSettings>("api/ClientAppSettings");
            AppSettings.BaseApiUrl = appSettings.BaseApiUrl;
            IsLoaded = true;
        }
    }
}

因为我们不能(或无法)将ClientAppSettings实例加载到依赖注入中,以使其在整个应用程序中可用,所以我只是将值放在静态类中。

现在,在MainLayout.razor中我们可以用AppSettingsLoader包装@body

<AppSettingsLoader>
@Body
</AppSettingsLoader>

最后,我们可以在Index.razor页面上引用AppSettings.BaseApiUrl。为了证明这一点,我将其显示在页面上。

@page "/"
<h1>Hello, world!</h1>

@AppSettings.BaseApiUrl

现在我们可以在AppSettings.jsonClientAppSettings部分设置任何我们喜欢的设置,它将被视为一个普通的应用设置,包括能够通过Azure应用服务的配置部分设置设置。

发布了70 篇原创文章 · 获赞 130 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/mzl87/article/details/103796335