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 的文件夹。并创建名为 dev 和 prod 的子文件夹。如下所示。
|- env
|- dev
|- prod
|
将不同的配置文件(具有相同名称和不同配置的文件)放在 dev 和 prod 文件夹中。
创建批处理文件以将适当的环境复制到 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。如果较新,请确保在属性部分将它们标记为复制。它们应该由构建自动拾取。
如何在客户端 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 的文件夹。并创建名为 dev 和 prod 的子文件夹。如下所示。
|- env
|- dev
|- prod
|
将不同的配置文件(具有相同名称和不同配置的文件)放在 dev 和 prod 文件夹中。
创建批处理文件以将适当的环境复制到 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。如果较新,请确保在属性部分将它们标记为复制。它们应该由构建自动拾取。