Is there a way to passing the Server Configuration (ASP.Net Core MVC WebApp with an appsettings.json) to the Client Project to be used by the Blazor Client? I try to pass e.g. the API-Url and I don't want to e.g. Hard-Code it in the Program.cs of the Blazor Client. Also cool would be if the appsettings.development.json would work too.
Currently I Hard-Code it into my Blazor Client:
public class Program
{
static void Main(string[] args)
{
var serviceProvider = new BrowserServiceProvider(services =>
{
// Add Blazor.Extensions.Logging.BrowserConsoleLogger
services.AddLogging(builder => builder
.AddBrowserConsole() // Register the logger with the ILoggerBuilder
.SetMinimumLevel(LogLevel.Debug) // Set the minimum log level to Information
);
services.Configure<HttpClientExtensionForMYAPIOptions>(options =>
{
options.Url = new Uri("https://MYAPI.MYDOMAIN.ch");
});
services.AddSingleton<HttpClientExtensionForMYAPI>();
});
new BrowserRenderer(serviceProvider).AddComponent<App>("app");
}
}
Wouldn't an appsettings.json usually include a variety of connection strings that you wouldn't necessarily want to expose to any client side app?
Would having a dictionary where you can specify, and read what properties in the appsettings.json that you want to expose to the client?
That way you're controlling the exposure of your server side config, and as your app grows you'll still have a single point of reference for all settings.
Sure, the connection string should not be exposed to the client and stay at the Web.Server side. But e.g. the API-Url should be configurable. So I could make an IOption
I can't see a configuration option to put on Web.Server e.g. in the public void ConfigureServices(IServiceCollection services)
. And there is also no option in the public void Configure([...])
to pass something to the client.
The only way it will get across to the client is via your server making it available via WebAPI etc.
You can do that easily with web api and sharing your configuration class between client / server : an action that loads the config, filters it, and send it to the client.
And this feature is a connection feature between web api and Blazor, or Blazor is supposed to work with any server side technology, at best it would be an external package.
You could also try embedding the config into the Blazor Assembly as well. And at your entry point you extract it and load the config as usual.
For conditional configs you could use MSBuild to conditionally Embed a different file when in DEBUG
or RELEASE
mode.
@RyoukoKonpaku solution sounds good to me.
Longer term we might consider some other method for embedding config info, but we'll have to see exactly what people are asking for. Hopefully you'll be OK with the embedded resource approach for now.
@RyoukoKonpaku That solution sounds good but do you have any examples of getting an embedded resources from an dll in client side Blazor?
@andrew6767 Here's how I configure my embedding at the moment.
On my Client.csproj
I have added an item group for embedding. The LogicalName
tag is the path you'd need later on retrieving the config from Code so It should at least be the same.
<ItemGroup>
<EmbeddedResource Include=".\Environment\config.dev.json" Condition="'$(Configuration)' == 'Debug'">
<LogicalName>config.json</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include=".\Environment\config.prod.json" Condition="'$(Configuration)' == 'Release'">
<LogicalName>config.json</LogicalName>
</EmbeddedResource>
</ItemGroup>
Then on the Startup.cs
I extract it like this.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(GetConfiguration());
}
public Configuration GetConfiguration()
{
// Get the configuration from embedded dll.
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("config.json"))
using (var reader = new StreamReader(stream))
{
return Json.Deserialize<Configuration>(reader.ReadToEnd());
}
}
Configuration
is just a class that matches the json I have for better usage.
Then with that you can access and setup some configuration it somewhere else via DI.
This solution still seems problematic because settings such as the api endpoints are hard coded in embedded resources and cannot be changed easily per deployment.
Using other spa frameworks I've passed in config as attributes on the app element, is it possible to do something like this in Blazor?
<app
authority="http://localhost:50405"
client-id="spa-blazor"
api-endpoint="http://someurl"
>Loading...</app>
and then retrieve those from within app code?
@joeaudette Yes, you can use JS interop to read anything from the DOM, so you could certainly pass config info that way if you want.
@SteveSandersonMS thanks! will give that a try
Most helpful comment
You can do that easily with web api and sharing your configuration class between client / server : an action that loads the config, filters it, and send it to the client.
And this feature is a connection feature between web api and Blazor, or Blazor is supposed to work with any server side technology, at best it would be an external package.