Reputation: 5459
How can I manage access variables which differ among environments in client side blazor? Normally since I use Azure to publish applications, I'd use the appsettings.json
file for local app settings and then set up entries in the Azure Application Settings section of my App Service for entries that differ between local environments and other environments.
An example of what I'm looking to accomplish:
Client side Blazor:
@functions {
//...more code here
await Http.PostJsonAsync<object>("http://localhost:50466/api/auth/register", vm);
}
on the deployed web server this should be transformed to:
@functions {
//...more code here
await Http.PostJsonAsync<object>("http://wwww.mywebsite.com/api/auth/register", vm);
}
So I'm looking for a way to store the site root url in an environment variable and transform it upon publish. Is there a Blazor-ey way to do this?
Upvotes: 15
Views: 17249
Reputation: 181
In Net Core 3.1 and Net 5 you can just create in the wwwroot the additional files for your environments: I have wwwroot/appsettings.json; and then also in the wwwroot the appsettings.Development.json and appsettings.Production.json. Make sure you mark them as Copy if newer in the Properties section. They should be picked up automatically by the build.
Upvotes: 0
Reputation:
I use Environment variables for all my Blazor sites:
This class EnvironmentVariableHelper is part of Nuget package 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
}
}
To create an Environment Variable, in Windows 10 Search Box start typing:
Edit System Environment Variables
Then make sure to add your variable to the System Environment Variables at the bottom (not the top section, as that is only for your user account and it won't work).
Then enter a variable name and a value and hit 'OK'.
Then to use it:
string value = EnvironmentVariableHelper.GetEnvironmentVariableValue("Variable Name");
Upvotes: 0
Reputation: 1667
appsettings are now supported in blazor directly so you can inject it: https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-preview-3-release-now-available/
Upvotes: 4
Reputation: 1502
My solution was creating the 3 corresponding files in the root project solution
then in pre-build event of your project replace the correct file to wwwroot directory
if $(ConfigurationName) == Debug (
copy /Y "$(ProjectDir)appsettings.Debug.json" "$(TargetDir)..\..\..\wwwroot\appsettings.json") ELSE (
copy /Y "$(ProjectDir)appsettings.Release.json" "$(TargetDir)..\..\..\wwwroot\appsettings.json" )
Upvotes: 1
Reputation: 263
In addition to the answer from @Kliment Ru, there is also this possibility where you can use the configuration file directly in the page and you don't have to implement a separate DTO as a variable holder:
appsettings.json (you can use SlowCheetah to create debug and release files and override the parameters):
{
"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
}
}
and in razor page you have:
@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)
}
}
Upvotes: 0
Reputation: 2137
You can create singleton with configuration interface and inject it in you components.
.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;
Or look this issue
Upvotes: 5
Reputation: 7248
There are multiple ways use can do this,
I believe there is no any official method documented yet!
My recommendation is to use the good old method, using multiple config files for different environments and copying only the config files to be used in the intended environemnt.
Create a folder called env in the solution folder. and create sub folders called dev and prod. like below.
|- env
|- dev
|- prod
|
Place your different config files (file with same name and different configs) inside dev and prod folders.
Create a batch file to copy appropreate environment to wwwroot
folder. (I prefer this than the next step since, this is much CI friendly , no need to install Visual Studio in build server)
OR
add the below code to the post-build event
of the Blazor Project
if $(ConfigurationName) == Debug (
copy /Y "$(ProjectDir)env\dev\*" "$(TargetDir)\wwwroot"
) ELSE (
copy /Y "$(ProjectDir)env\prod\*" "$(TargetDir)\wwwroot"
)
Since your config file is in the www folder you can easily refer this from the blazor app by opening the file and reading whats inside this.
Upvotes: 3