简体   繁体   中英

Accessing Configuration Settings in Javascript using ASP.NET Core 2 MVC

I'm currently building a simple website using ASP.NET Core 2 and bootstrap. The site will be deployed to a staging and production environment so I want to be able to configure some settings using Configuration Key/Value pairs I can set in Azure. I also want these values to be available to me in Javascript.

Thanks to this helpful blog post I have worked out how to create an AppSettings class and populate it. This post also covers using dependency injection to access AppSettings from a RazorPage model.

My appsettings.json file

{
    "AppSettings": {
        "TestProperty": "Test_Property"
    },
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "Default": "Warning"
        }
    }
}

Automatically bind my AppSettings class in Startup.cs

services.Configure<AppSettings>(Configuration.GetSection(nameOf(AppSettings)));

Accessing the settings via dependency injection:

public class HomeModel : PageModel
{
    private readonly AppSettings _appSettings;

    public string TestProperty {get; set;}

    public HomeModel(IOptions<AppSettings> appSettings)
    {
        _appSettings = appSettings.Value;
    }

    public IActionResult Index()
    {
        TestProperty = _appSettings.TestProperty;

        return View();
    }
}

Then on the page where I want to use this property in javascript I do the following to create a javascript property with the setting:

<script type="text/javascript">
  var testProperty = '@Model.TestProperty';
</script>

This works but ideally I don't want to have to configure every page to use this dependency injection and expose my TestProperty on every page. I would like to be able to put the above code in my _Layout.cshtml in which every page's body is rendered (or somewhere else appropriate) so I can create a javascript variable for use on every page.

I have thought about using a BaseViewModel from which all my page's models are inherited but experimenting with this hasn't resulted in anything useful (just a exceptions).

How would you go about creating a javascript property from a configuration setting with the ability to configure only once?

I've come up with something that works the way I need but very interested to hear other suggestions, my way could well be far from the best..

I stumbled across this blog post which talks about the MVC6 keyword, @inject . Using this it is possible to inject dependencies into Razor views.

Using this I added the following to the top of my _Layout.cshtml file:

@inject IAppSettings AppSettings; 

I could then reference properties of AppSettings in this view using:

<script type="text/javascript">
        var testProperty = '@AppSettings.TestProperty';
    </script>

I then edited my Startup.cs class to register IAppSettings and creates an AppSettings factory that reads the appsettings.json file and makes a new AppSettings class when required:

services.AddSingleton<IAppSettings, AppSettings>(e => Configuration.GetSection(nameof(AppSettings)).Get<AppSettings>());

This works a treat and I can access my javascript testProperty everywhere in my application but I'm curious if anyone has any other ideas as to how this could be done differently (perhaps using a BaseViewModel)?

Updated: As requested, here is more information on my implementation:

My IAppSettingsService interface:

public interface IAppSettingsService
    {
        string AzureStorageAccountName { get; }
        string AzureStorageAccountKey { get; }
    }

My AppSettingsService implementation:

public class AppSettingsService : IAppSettingsService
{
    public string AzureStorageAccountName { get; set; }
    public string AzureStorageAccountKey { get; set; }
}

The AppSettings.json:

{
    "AppSettings": {
        "AzureStorageAccountName": "XXXXXXXXXX",
        "AzureStorageAccountKey": "XXXXXXXXXX"
    },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  }
}

Then in the Azure Portal I can change these values at any time using AppSettings:AzureStorageAccountName and setting the value to the required information in the App Settings section.

not sure what exactly you are trying to achieve. But pretty much what you have is the way you will access the appsettings in JavaScript. Injecting objects/services to view is a great thing in ASP.NET Core.

if you are just looking at URLs for different environments - you can achieve it in your release pipelines. In my day job - i work on a web app which is asp.net core as host + angular 2 as UI framework. We have 4 environments. angular code always makes call to our asp.net core host. we have a middleware written which looks for api calls and forwards them to our APIs hosted on azure in respective environments. The domain of the api environment is kept as an appsetting key. In our release pipeline - we override the property for each environment release.

Its best to centralize everything in your asp.net server side code. The UI ie JavaScript should just ping your server side MVC controller end point. That way you can parameterize the application settings during release.

hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM