Blazor:管理环境特定变量

Blazor: Managing Environment Specific Variables

如何在客户端 blazor 中管理因环境而异的访问变量?通常,因为我使用 Azure 发布应用程序,所以我会使用 appsettings.json 文件进行本地应用程序设置,然后在我的应用程序服务的 Azure 应用程序设置部分中设置条目,以获取本地环境和其他环境之间不同的条目。

我希望完成的示例:

客户端 Blazor:

@functions {
    //...more code here
    await Http.PostJsonAsync<object>("http://localhost:50466/api/auth/register", vm);
}

在已部署的 Web 服务器上,这应转换为:

@functions {
    //...more code here
    await Http.PostJsonAsync<object>("http://wwww.mywebsite.com/api/auth/register", vm);
}

所以我正在寻找一种方法来将站点根 url 存储在环境变量中并在发布时对其进行转换。有没有一种 Blazor-ey 的方法可以做到这一点?

有多种方法可以做到这一点,

I believe there is no any official method documented yet!

我的建议是使用老方法,为不同的环境使用多个配置文件,并只复制要在预期环境中使用的配置文件。

在解决方案文件夹中创建一个名为 env 的文件夹。并创建名为 devprod 的子文件夹。如下所示。

|- env
   |- dev
   |- prod
   |

将不同的配置文件(具有相同名称和不同配置的文件)放在 devprod 文件夹中。

创建批处理文件以将适当的环境复制到 wwwroot 文件夹。 (我更喜欢这个而不是下一步,因为这 CI 非常友好 ,不需要安装 Visual Studio构建服务器)

将以下代码添加到 Blazor 项目

post-build event
if $(ConfigurationName) == Debug (
  copy /Y "$(ProjectDir)env\dev\*" "$(TargetDir)\wwwroot"
) ELSE (
  copy /Y "$(ProjectDir)env\prod\*" "$(TargetDir)\wwwroot"
)

由于您的配置文件位于 www 文件夹中,您可以通过打开文件并阅读其中的内容,轻松地从 blazor 应用程序引用它。

您可以使用配置接口创建单例并将其注入您的组件。

.csproj

<ItemGroup>
   <EmbeddedResource Include="appsettings.Development.json" Condition="'$(Configuration)' == 'Debug'">
     <LogicalName>appsettings.json</LogicalName>
   </EmbeddedResource>
   <EmbeddedResource Include="appsettings.json" Condition="'$(Configuration)' == 'Release'">
      <LogicalName>appsettings.json</LogicalName>
   </EmbeddedResource>
</ItemGroup>

Startup.cs

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton(GetConfiguration());
    }

    private IConfiguration GetConfiguration()
    {
        // Get the configuration from embedded dll.
        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("appsettings.json"))
        using (var reader = new StreamReader(stream))
        {
            return JsonConvert.DeserializeObject<IConfiguration>(reader.ReadToEnd());
        }
    }

MyComponent.razor

@inject Configuration.IConfiguration Configuration;

或者看这个issue

除了@Kliment Ru 的回答之外,还有这种可能性,您可以直接在页面中使用配置文件,而不必实现单独的 DTO 作为变量持有者:

appsettings.json(您可以使用SlowCheetah创建调试和发布文件并覆盖参数):

{
    "Host": "bla"
}

Startup.cs

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton(GetConfiguration());
    }

    public void Configure(IComponentsApplicationBuilder app)
    {
        app.AddComponent<App>("app");
    }

    private IConfiguration GetConfiguration()
    {
        using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("appsettings.json");
        return new ConfigurationBuilder()
            .AddJsonStream(stream) // key method to use, reads JSON stream
            .Build(); // builds the configuration from embedded stream
    }
}

在 razor 页面中你有:

@page "/Task/list"
@inject HttpClient http
@inject Microsoft.Extensions.Configuration.IConfiguration configuration

...some HTML code

@code {
    private IEnumerable<Model.StoreTask> storeTasks;

    protected override async Task OnInitializedAsync()
    {
        storeTasks = await http.GetJsonAsync<IEnumerable<Model.StoreTask>>(configuration["Host"] + "GetStoreTasks"); // you can use the configuration directly (bla/GetStoreTasks)
    }
}

我的解决方案是在根项目解决方案中创建 3 个对应的文件

  • appsettings.json
  • appsettings.Debug.json
  • appsettings.Release.json

然后在项目的 预构建 事件中将正确的文件替换到 wwwroot 目录

if $(ConfigurationName) == Debug (
copy /Y "$(ProjectDir)appsettings.Debug.json" "$(TargetDir)..\..\..\wwwroot\appsettings.json"

) ELSE (
copy /Y "$(ProjectDir)appsettings.Release.json" "$(TargetDir)..\..\..\wwwroot\appsettings.json" )

appsettings 现在直接在 blazor 中支持,因此您可以注入它: https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-preview-3-release-now-available/

我为所有 Blazor 站点使用环境变量:

这个 class EnvironmentVariableHelper 是 Nuget 包的一部分 DataJuggler.UltimateHelper.Core

using System;
using System.Collections.Generic;
using System.Text;

namespace DataJuggler.UltimateHelper.Core
{
    public class EnvironmentVariableHelper
    {

        #region Methods

            #region GetEnvironmentVariableValue(string variableName)
            /// <summary>
            /// This method is used to get an environment value
            /// </summary>
            /// <param name="variableName"></param>
            /// <returns></returns>
            public static string GetEnvironmentVariableValue(string variableName)
            {
                // initial value
                string value = "";

                try
                {
                    if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                    {
                        // Change the directory to %WINDIR%
                        value = Environment.GetEnvironmentVariable(variableName, EnvironmentVariableTarget.Machine);
                    }
                }
                catch (Exception error)
                {
                    // for debugging only, do something else with it if you need to
                    DebugHelper.WriteDebugError("GetEnvironmentVariableValue", "GetEnvironmentVariableValue", error);
                }

                // return value
                return value;
            }
            #endregion

        #endregion

    }
}

要创建环境变量,请在 Windows 10 搜索框中开始输入:

编辑系统环境变量

然后确保将您的变量添加到底部的系统环境变量中(不是顶部部分,因为那仅适用于您的用户帐户,不会起作用)。

然后输入一个变量名和一个值并点击'OK'。

然后使用它:

string value = EnvironmentVariableHelper.GetEnvironmentVariableValue("Variable Name");

在 Net Core 3.1 和 Net 5 中,您只需在 wwwroot 中为您的环境创建附加文件:我有 wwwroot/appsettings.json;然后还在 wwwroot 中 appsettings.Development.json 和 appsettings.Production.json。如果较新,请确保在属性部分将它们标记为复制。它们应该由构建自动拾取。