Aspnetcore: Passing Server Configuration (appsettings.json) to the Blazor Client

Created on 19 Jul 2018  路  11Comments  路  Source: dotnet/aspnetcore

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");
        }
    }
area-blazor

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.

All 11 comments

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 class (or a dictionary) which reads the server side appsettings.json and passes this class to the Web.Client? But how and where?

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

Was this page helpful?
0 / 5 - 0 ratings