如何在Blazor WebAssembly中访问appsettings

30

我目前正在尝试将API URL保存在应用程序设置中。 但是,configuration.Properties似乎为空。我不确定如何获取该设置。 在program.cs中:

public static async Task Main(string[] args)
{
   var builder = WebAssemblyHostBuilder.CreateDefault(args);
   //string url = builder.Configuration.Properties["APIURL"].ToString();
   foreach (var prop in builder.Configuration.Properties)
      Console.WriteLine($"{prop.Key} : {prop.Value}" );
   //builder.Services.AddSingleton<Service>(new Service(url));
   builder.RootComponents.Add<App>("app");
   await builder.Build().RunAsync();
}

没有一种简单的方法可以将设置直接传递到客户端 Blazor 应用程序中,因此我们需要应用程序从服务器请求它们。我们将创建一个 ClientAppSettingsController 来为 AppSettingsExample.Server 提供这些设置。 - claudiom248
有用的问题:https://dev59.com/Kbvpa4cB1Zd3GeqPCf9D -- 应用于IConfiguration服务 - M.M
10个回答

27

使用 ASP.NET Core 6.0 Blazor 配置。默认情况下,Blazor WebAssembly 从以下应用程序设置文件中加载配置:

  • wwwroot/appsettings.json。
  • wwwroot/appsettings.{ENVIRONMENT}.json,其中 {ENVIRONMENT} 是应用程序的 运行时环境 占位符。

例如:

wwwroot/appsettings.json

{
  "h1FontSize": "50px"
}

Pages/ConfigurationExample.razor

@page "/configuration-example"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example
</h1>

警告:Blazor WebAssembly应用程序中的配置和设置文件对用户可见。不要将应用程序机密、凭据或任何其他敏感数据存储在Blazor WebAssembly应用程序的配置或文件中。

https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/configuration?view=aspnetcore-6.0

您还可以将值绑定到类。

public class ClientAppSettings
{
    public string h1FontSize{ get; set; }
}

然后在 Program.cs 中将该类添加为单例模式:

var settings = new ClientAppSettings();
builder.Configuration.Bind(settings);
builder.Services.AddSingleton(settings);

_Imports.razor文件中添加命名空间,然后在需要的地方注入以在Visual Studio中获得具有自动完成功能的设置:

@inject ClientAppSettings ClientAppSettings

你的回答帮助了我在一个糟糕的Pluralsight课程实验中,直到我读到你有关appsettings.json文件自动被拾取的提示才能继续前进。谢谢。 - Tore Aurstad
谢谢,我使用了你的Configuration.Bind方法来绑定appSettings.json中的一个组节。我在下面发布了答案,但是你应该得到所有的功劳! - JClarkCDS

18
Inkkiller做得很好。你可以简化对IConfiguration的调用,不需要使用APIHelper类,直接从WebAssemblyHostBuilder中的Program.cs进行访问。
appsettings:
{
   "ServerlessBaseURI": "http://localhost:0000/",
}

程序.cs:

public static async Task Main(string[] args)
{
    var builder = WebAssemblyHostBuilder.CreateDefault(args);

    string serverlessBaseURI = builder.Configuration["ServerlessBaseURI"];
}



16
这个回答涉及到了Blazor预览版,当Blazor还不支持在wwwroot文件夹中使用appsettings.json时。现在你应该使用wwroot文件夹中的appsettings.json和WebAssemblyHostBuilder.Configuration。它还支持按环境分文件(appsettings.{env}.Json)。
我通过在应用的wwwroot文件夹中使用一个settings.json文件来解决了这个问题,并注册了一个任务来获取这些设置。

Settings.cs

public class Settings
{
    public string ApiUrl { get; set; }
}

wwwroot/settings.json

{
   "ApiUrl": "https://localhost:51443/api"
}

Progam.cs

public static async Task Main(string[] args)
{
    var builder = WebAssemblyHostBuilder.CreateDefault(args);

    builder.Services.AddSingleton(async p =>
    {
        var httpClient = p.GetRequiredService<HttpClient>();
        return await httpClient.GetFromJsonAsync<Settings>("settings.json")
            .ConfigureAwait(false);
    });

SampleComponent.razor

@inject Task<Settings> getsettingsTask
@inject HttpClient client
...
@code {
    private async Task CallApi()
    {
        var settings = await getsettingsTask();
        var response = await client.GetFromJsonAsync<SomeResult>(settings.ApiUrl);
    }
}

这有一些优点:
- 不共享服务器的appsettings.json文件,这可能会成为一个安全隐患 - 可以根据环境进行配置

非常感谢!昨天我终于理解了它。 - Zo.
1
从.NET 5开始,它实际上被称为GetFromJsonAsync - JBSnorro

10

您也可以直接在wwwroot中使用appsettings.json文件:

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

        var url = builder.Configuration.GetValue<string>("ApiConfig:Url");
        builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(url) });
    }
}

这是问题的确切答案。在 net6 中,没有 class Program { ... } 也是一样的。 - Sith2021

8

目前,您可以使用 IConfiguration 接口。

appsettings.json 文件:

{
  "Services": {
    "apiURL": "https://localhost:11111/"
  }
}

.

using Microsoft.Extensions.Configuration;

public class APIHelper
    {
        private string apiURL;

        public APIHelper(IConfiguration config)
        {
            apiURL = config.GetSection("Services")["apiURL"];
            //Other Stuff
        }

    }

6

Blazor WASM appsettings.json

如果您在wwwroot文件夹中没有appsettings.json,则可以简单地执行以下操作:

  1. 右键单击 wwwroot 文件夹。
  2. 点击“添加”==>“新项目”==>“应用程序设置文件”

这将向您的应用程序添加appsettings.json。 打开appsettings.json文件,您会看到其中已经有一个关于数据库的部分,请像我添加了apiinfo一样添加一个部分:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;MultipleActiveResultSets=true"
  },

  "apiinfo":{
    "apiurl": "your api url"
  }

}

现在,当你想要调用这个部分的时候,只需要注入配置并按以下方式进行调用:
@inject Microsoft.Extensions.Configuration.IConfiguration config;

调用apiurl

config.GetSection("apiinfo")["apiurl"].ToString()

3
在 .Net 5 & 6 中,您可以将值设置为静态类。
示例:
wwwroot/appsettings.json
 "ServicesUrlOptions": {
   "Url": "https://domain.gr/services" }

Static Class

public static class ApplicationServicesSettings
{
    public const string ServicesUrl = "ServicesUrlOptions";
    public static ServicesUrlOptions ServicesUrlOptions { get; set; } = new ServicesUrlOptions();
}

public class ServicesUrlOptions
{
    public string Url { get; set; }
}

最后在 Program.cs 中绑定该值。

 builder.Configuration.GetSection(ApplicationServicesSettings.ServicesUrl).Bind(ApplicationServicesSettings.ServicesUrlOptions);

在项目中,您可以通过以下方式访问密钥:
ApplicationServicesSettings.ServicesUrlOptions.Url

2
作为一个例子,我已经实现了这样的方式(客户端 Blazor):
appsettings.json:
{
    "api": "https://www.webapiurl.com/"
    "ForceHTTPS": false
}

那么,已经编写了配置类。
 public class APISetting
    {

        public string api { get; set; }

        public bool ForceHTTPS { get; set; }

    }

然后,在启动时加载:

public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton(GetConfiguration());
        }
        public void Configure(IComponentsApplicationBuilder app )
        {
            app.AddComponent<App>("app");
        }

        public APISetting GetConfiguration()
        {
            using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("appsettings.json"))
            using (var reader = new System.IO.StreamReader(stream))
            {
                return System.Text.Json.JsonSerializer.Deserialize<APISetting>(reader.ReadToEnd());
            }
        }
    }

我的应用程序没有startup.cs文件。 所有的东西都通过program.cs进行处理。 mars的agua答案可以解决这个问题。 - Zo.
1
不相关的...我希望人们在投反对票时能提供一些细节... - yob
1
我相信它开始过时了。 - Zo.

2

在 @Ogglas 的回答基础上进行扩展。我将服务的 Configuration.Bind 更改为绑定 appSettings.json 文件中的一个部分。

appSettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "myappSettings": {
    "Company": "ACME Sandbox",
    "ApiEndpoint": "https://api.sample.com:50443/",
    "ImageLocation": "\\\\OnPremise.sample.local\\Images",
    "ImageUrl": "https://cdn.somesite.com",
    "Emails": {
      "RequestTo": "team@degensrt.com",
      "SubmittedTo": "team@degensrt.com",
    }
  }
}

myappSettings.cs

public class myappSettings
{
    public string Company { get; set; }
    public string ApiEndpoint { get; set; }
    public string ImageLocation { get; set; }
    public string ImageUrl { get; set; }
    public appEmails Emails { get; set; }
}

public class appEmails
{
    public string RequestTo { get; set; }
    public string SubmittedTo { get; set; }
}

然后在Program.cs中注册并绑定到myappSettings部分。
//Application Settings
var settings = new myappSettings();
builder.Configuration.Bind("myappSettings", settings);
builder.Services.AddSingleton(settings);

然后在您的组件中进行注入和使用:

@inject appSettings appSettings;
....
....
@code {
private string EmailTo = "";
    
protected override async Task OnInitializedAsync()
{
    EmailTo = appSettings.Emails.SubmittedTo;
}
}

0

创建设置类:

public class Settings
{
    public string ApiUrl { get; set; }
}

在wwwroot文件夹中创建settings.json:

{
    "ApiUrl": "http://myapiurlhere"
}

在 .razor 组件中,可以这样读取:

@inject HttpClient Http
...
@code {
    private string WebApuUrl = "";

    protected override async Task OnInitializedAsync()
    {
        var response = await Http.GetFromJsonAsync<Settings>("settings.json");
        WebApuUrl = response.ApiUrl;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接