【问题标题】:Blazor: Managing Environment Specific VariablesBlazor:管理环境特定变量
【发布时间】:2019-06-25 00:29:21
【问题描述】:

如何管理客户端 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 的方式来做到这一点?

【问题讨论】:

    标签: c# asp.net-core .net-core blazor


    【解决方案1】:

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

    .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

    【讨论】:

    • 我正在尝试使用此代码,但收到错误消息:Newtonsoft.Json.JsonSerializationException: 'Could not create an instance of type Microsoft.Extensions.Configuration.IConfiguration.类型是接口或抽象类,不能实例化。我错过了什么?
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      相信还没有任何官方方法记录在案!

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

      在解决方案文件夹中创建一个名为 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 应用程序中引用此文件。

      【讨论】:

        【解决方案4】:

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

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

        然后在您项目的 pre-build 事件中将正确的文件替换到 wwwroot 目录

        如果 $(ConfigurationName) == 调试 (
        复制 /Y "$(ProjectDir)appsettings.Debug.json" "$(TargetDir)..\..\..\wwwroot\appsettings.json"

        ) 其他(
        复制 /Y "$(ProjectDir)appsettings.Release.json" “$(目标目录)..\..\..\wwwroot\appsettings.json” )

        【讨论】:

          【解决方案5】:

          我对所有 Blazor 网站都使用环境变量:

          这个类 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 搜索框中开始输入:

          编辑系统环境变量

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

          然后输入变量名和值并点击“确定”。

          然后使用它:

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

          【讨论】:

            【解决方案6】:

            除了@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
                }
            }
            

            在剃须刀页面中你有:

            @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)
                }
            }
            

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2018-01-17
                • 1970-01-01
                • 2020-04-16
                • 1970-01-01
                • 1970-01-01
                • 2014-11-13
                • 2015-07-09
                • 1970-01-01
                相关资源
                最近更新 更多