10

In this example, Hosting Blazor, the author has a Blazor ClientSide App that calls Azure Functions. The author sets a Http.BaseAddress. Any thoughts on the best way to configure the Client Side Blazor "Http.BaseAddress" for a local URL when debugging and the Azure Functions URL when the Blazor app is deployed to Azure folders?

Debugging:
Http.BaseAddress = new Uri("https://localhost:12345");

Production:
Http.BaseAddress = new Uri("https://blazorapi.azurewebsites.net");

@functions {
Book[] books;
string message;
  protected override async Task OnInitAsync()
  {
    message = "OnInitAsync";
    Http.BaseAddress = new Uri("https://blazorapi.azurewebsites.net");
    books = await Http.GetJsonAsync<Book[]>("/api/BooksFunction");
    message = "downloaded books";
  }
}
Vibeeshan Mahadeva
  • 7,147
  • 8
  • 52
  • 102
  • This is a stand a lone Blazor app, right ? It only runs in the browser, so how can you debug it, anyway?Presently, debugging is poorly supported unless you use Razor Components. – enet Jan 26 '19 at 15:21
  • By debugging I mean running locally. fyi, Chrome includes a web assembly debugger (beta). –  Jan 26 '19 at 15:50
  • 1
    Just in case you haven't found your solution somewhere else by now: I updated my answer for a "right" solution now. – Squirrelkiller May 07 '20 at 15:59

1 Answers1

11

Update because Blazor got more complete:

By now, Blazor actually has the config-process we're used to from other .NET Applications, just a litte more...frontend-y:

You create an appsettings.json file for special configurations, like appsettings.Release.json. For Blazor you have to put it into the wwwroot folder.
The file should look something like this:

{
  "BaseUrl": "https://localhost:12345"
}

And in your appsettings.Release.json, you would put your prod url instead of localhost. You can now go into your Program.cs and read the settings like this:

baseAddress = builder.Configuration.GetValue<string>("BaseUrl");
builder.Services.AddSingleton(new HttpClient 
{ 
    BaseAddress = new Uri(baseAddress) }
);

Now all your class constructed automatically, like components, can use DI to get the configured HttpClient. You just put this at the top:

@inject HttpClient Http

And then use it from there. Of course use the DI scope of your choosing here (Transient/Scoped/Singleton).

Or, you know, just save the baseAddress somewhere if you don't wanna use DI.

This comes with preview-5, but we're even further by now with RC-1

Blazor is in production now, no need to play around with preview versions anymore.


Old answer:

As far as I know there isn't a "good" way of getting the environment yet, but since it's only about prod vs dev, you can do hte same as me and just use compiler variables old school style:

public class Program
{
    internal const string BaseAddress = "http://localhost:81/";
    internal const string ProdBaseAddress = "http://localhost:5001/";

    public static async Task Main(string[] args)
    {
        var builder = WebAssemblyHostBuilder.CreateDefault(args);
        builder.RootComponents.Add<App>("app");

        var host = builder.Build();
        var httpClient = host.Services.GetRequiredService<HttpClient>();
#if DEBUG
        httpClient.BaseAddress = new Uri(BaseAddress);
#else
        httpClient.BaseAddress = new Uri(ProdBaseAddress);
#endif

        Console.WriteLine($"Set BaseAddress: {BaseAddress}");
        await host.RunAsync();
    }
}

Just make sure the DEBUG variable is actually set in your Debug build - mine was not.

Edit: Forgot the point: Locally you're likely using 'Debug' config, while when deploying you probably have a different config, like 'Release'.

Squirrelkiller
  • 2,575
  • 1
  • 22
  • 41
  • You could also wrap the ProdBaseAddress in a `#if !DEBUG` so it's not dangling during development. – Squirrelkiller Feb 15 '20 at 21:57
  • I would avoid compiler variables. I'd rather use environment variables. That's how Cloud platforms work: you can host an app, setting all the variables you want; in an ASP.NET Core app, you find all of them in the IConfiguration object, as normal plain C# values. The code is cleaner this way, you don't have continuous #if/#else. – Massimiliano Kraus May 06 '20 at 07:17
  • 2
    Good point. Also by now, Blazor includes the usual way for getting config from an appsettings file. I will update my answer to reflect that. – Squirrelkiller May 07 '20 at 15:37
  • What when I want to share the client as docker image? I can't map appsettings - dotnet generates compressed files from the original `appsettings.{env}.json` files – boop Mar 29 '21 at 23:04
  • @boop, if you overwrite regular files, the regular files will be read instead of compressed ones. Maybe you will find this useful as well: https://stackoverflow.com/questions/66744484/how-to-override-blazor-client-configuration-with-environment-variables – astrowalker Apr 09 '21 at 10:40