MAUI: What build action for appsettings.json and how to access the file on Android?
Asked Answered
B

7

8

I created an appsettings file for a MAUI app and loading it in the IConfiguration using .Host.ConfigureAppConfiguration on the builder from a MauiApp.CreateBuilder(); I can access the file in Windows but not when running the Android emulator. The code:

 var builder = MauiApp.CreateBuilder();
            builder
                .RegisterBlazorMauiWebView()
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                })
                .Host
                .ConfigureAppConfiguration((app, config) =>
                {
#if __ANDROID__
                    // https://mcmap.net/q/1322622/-accessing-files-through-a-physical-path-in-xamarin-android
                    //var documentsFolderPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
                    config.AddJsonFile( "appsettings.json", optional: false, reloadOnChange: true);
#endif

#if WINDOWS10_0_17763_0_OR_GREATER
                    //https://mcmap.net/q/1322623/-how-to-load-app-configuration-from-appsettings-json-in-maui-startup
                    Assembly callingAssembly = Assembly.GetEntryAssembly();
                    Version versionRuntime = callingAssembly.GetName().Version;
                    string assemblyLocation = Path.GetDirectoryName(System.AppContext.BaseDirectory); //CallingAssembly.Location
                    var configFile = Path.Combine(assemblyLocation, "appsettings.json");
                    config.AddJsonFile(configFile, optional: false, reloadOnChange: true);
#endif
                });

Mockup project is here

Bresee answered 8/12, 2021 at 18:49 Comment(1)
For newcomers, jump to the summary here.Coriander
A
4

There is an open issue Add support for appsetting.json.

This code snippet from issue 3446 is one work-around:

var builder = MauiApp.CreateBuilder();
        builder
            .RegisterBlazorMauiWebView()
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            })
            .ConfigureAppConfiguration((app, config) =>
            {
                var assembly = typeof(App).GetTypeInfo().Assembly;
                config.AddJsonFile(new EmbeddedFileProvider(assembly), "appsettings.json", optional: false, false);
            });

Note the use of EmbeddedFileProvider. This works with Build Action EmbeddedResource.


UPDATE in above code, removed use of .Host, now that ConfigureAppConfiguration is directly on AppBuilder.


UPDATE 2 See Yepeekai's answer for newer solution. CAVEAT: I have not tested it though.


UPDATE 3 James Montemagno’s code to support appsettings.json. This link is from a comment in the open issue.

Ardenardency answered 9/12, 2021 at 2:36 Comment(0)
D
8

As of GA of MAUI: Add 2 nuget packages:

  • Microsoft.Extensions.Configuration.Binder
  • Microsoft.Extensions.Configuration.Json

then in MauiProgram.cs, add:

using var stream = Assembly.GetExecutingAssembly()
    .GetManifestResourceStream("YourAppName.appsettings.json");
var config = new ConfigurationBuilder().AddJsonStream(stream).Build();
builder.Configuration.AddConfiguration(config);

Reference: https://montemagno.com/dotnet-maui-appsettings-json-configuration/

Dakar answered 31/5, 2022 at 21:17 Comment(2)
a.GetManifestResourceStream("jsonfile") is always null (stream is null), Even the file is added as an Embedded Resource. Any ideas?Synergistic
Okay. figured it out. In "YourAppName.appsettings.json", "YourAppName" should be the namespace of the assembly, which is quite obvious for the embedded resources, but I missed that part :DSynergistic
M
7

This seems to work for me in a .net 7 Maui Blazor app

var config = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .Build();

builder.Configuration.AddConfiguration(config);

Make sure to set the appsettings file as an embedded resource in properties.

Maris answered 22/11, 2022 at 14:7 Comment(2)
Nice, I did not have to add any Nuget packages for this. Works also in .net 6 Maui Blazor app.Artemis
Somehow, it's not working for me. I am using .net 7 Blazor MAUI.Ossification
A
4

There is an open issue Add support for appsetting.json.

This code snippet from issue 3446 is one work-around:

var builder = MauiApp.CreateBuilder();
        builder
            .RegisterBlazorMauiWebView()
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            })
            .ConfigureAppConfiguration((app, config) =>
            {
                var assembly = typeof(App).GetTypeInfo().Assembly;
                config.AddJsonFile(new EmbeddedFileProvider(assembly), "appsettings.json", optional: false, false);
            });

Note the use of EmbeddedFileProvider. This works with Build Action EmbeddedResource.


UPDATE in above code, removed use of .Host, now that ConfigureAppConfiguration is directly on AppBuilder.


UPDATE 2 See Yepeekai's answer for newer solution. CAVEAT: I have not tested it though.


UPDATE 3 James Montemagno’s code to support appsettings.json. This link is from a comment in the open issue.

Ardenardency answered 9/12, 2021 at 2:36 Comment(0)
O
3

From .NET MAUI Preview 13, Host is removed (https://github.com/dotnet/maui/pull/4505). The exact same code in the accepted answer may not work.
Until appsettings.json is supported by MAUI (I hope the MAUI team will support it), I make my appsettings.json an Embedded resource and load and inject the contents like this.

var builder = MauiApp.CreateBuilder();

var assembly = Assembly.GetExecutingAssembly();

// appsettings.json is located directly under MyNamespace.csproj
using var stream = assembly.GetManifestResourceStream("MyNamespace.appsettings.json");
stream.Position = 0;
var appSettings = System.Text.Json.JsonSerializer.Deserialize<AppSettings>(stream);

builder.Services.AddSingleton(appSettings)

This may not be the best way to load the file but it works and it's good enough for me.
If there is a better way, I'd like to know it.

References: https://redth.codes/settings-json-files-in-xamarin-apps/

Outoftheway answered 20/2, 2022 at 2:47 Comment(2)
Host is removed but Configuration is added for MauiAppBuilder. While there's still no proper way, you can use builder.Configuration.AddJsonFile as it is mentioned in the accepted answer, or in the format I'm using now (which works with custom root namespace): builder.Configuration.AddJsonFile(new EmbeddedFileProvider(typeof(App).Assembly, typeof(App).Namespace), "appsettings.json", false, false);Coates
Re "The exact same code in the accepted answer may not work." - I've updated the accepted answer, to match the Maui API change.Ardenardency
S
0

Thought id add this encase it helps others, using @Yepeekai answer

In .NET Blazor Maui I found I only needed to use:

MauiProgram.cs

   var assembly = Assembly.GetExecutingAssembly();
   using var stream = assembly.GetManifestResourceStream("MyAppNameSpace.appsettings.json");

   var config = new ConfigurationBuilder()
            .AddJsonStream(stream)
            .Build();

   builder.Configuration.AddConfiguration(config);

Then in the page @code or as in this example a page base class you can use

IndexBase.cs

  [Inject]
  public IConfiguration _configuration { get; set; }

  protected override async Task OnInitializedAsync()
        {
           var settings = _configuration.GetRequiredSection("Settings").Get<Settings>();
           //Example usage:
           var foo = await _client.GetFromJsonAsync<SomeClass>($"{settings.SomePram}");
Seer answered 21/11, 2022 at 18:33 Comment(0)
A
0

Hey you can use this official tip for get a .json file in your .NET Maui app

Note: your .json file must to be in this path Resources/Raw

async Task LoadMauiAsset()
{
    using var stream = await FileSystem.OpenAppPackageFileAsync("filename.json");
    using var reader = new StreamReader(stream);

    var contents = reader.ReadToEnd();
}

I recommend to call this method in constructor Page Content.

Acetaldehyde answered 22/3, 2023 at 0:51 Comment(0)
C
0

Summary

  • appsettings.json can be placed in either a MAUI project or a class library project.

  • Build Action of appsettings.json can be either Embedded resource or MauiAsset. Note: a class library will have MauiAsset option if <UseMaui>true</UseMaui> is added to its *.csproj.

  • Stream when using Embedded resource:

    // asm depends on where appsettings.json is placed.  
    var asm = typeof(IClassLibraryMarker).Assembly;// appsettings.json in class library
    var asm = Assembly.GetExecutingAssembly();// appsettings.json in MAUI project
    
    var path = $"{asm.GetName().Name}.appsettings.json";
    using Stream stream = asm.GetManifestResourceStream(path);
    

    Stream when using MauiAsset:

    using var stream = FileSystem.OpenAppPackageFileAsync("appsettings.json").Result;
    
  • Registering configuration is the same. I use IOptions pattern here.

    // Microsoft.Extensions.Configuration.Json package
    builder.Configuration.AddJsonStream(stream!);
    
    // Microsoft.Extensions.Options.ConfigurationExtensions package
    builder.Services.AddOptions<MySettings>().BindConfiguration(MySettings.SECTION);
    

Complete Code

// appsettings.json
{
    "MySettings": {
        "Id": 1,
        "Message": "Hello World"
    }
}
public class MySettings
{
    public const string SECTION = nameof(MySettings);

    public int Id { get; set; }
    public string Message { get; set; } = null!;
}
#define EmbeddedResource
// ...
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();

#if EmbeddedResource
        var asm = typeof(IClassLibraryMarker).Assembly; 
        var asm = Assembly.GetExecutingAssembly();
        var path = $"{asm.GetName().Name}.appsettings.json";
        using var stream = asm.GetManifestResourceStream(path);
#else
        using var stream = FileSystem.OpenAppPackageFileAsync("appsettings.json").Result;
#endif

        builder.Configuration.AddJsonStream(stream!);
        builder.Services.AddOptions<MySettings>().BindConfiguration(MySettings.SECTION);

        // ...
    }
}
Coriander answered 31/8, 2024 at 6:22 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.