使用ASP.NET Core 2 MVC在Javascript中访问配置设置

时间:2017-12-28 15:46:27

标签: asp.net razor asp.net-core asp.net-core-mvc

我目前正在使用ASP.NET Core 2和bootstrap构建一个简单的网站。该站点将部署到登台和生产环境,因此我希望能够使用我可以在Azure中设置的配置键/值对来配置一些设置。我也想在Javascript中使用这些值。

感谢这个helpful blog post我已经研究了如何创建AppSettings类并填充它。这篇文章还介绍了如何使用依赖注入来从RazorPage模型访问AppSettings。

我的appsettings.json文件

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

在Startup.cs中自动绑定我的AppSettings类

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

通过依赖注入访问设置:

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();
    }
}

然后在我想在javascript中使用此属性的页面上,我执行以下操作以使用以下设置创建javascript属性:

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

这很有效,但理想情况下,我不希望必须配置每个页面以使用此依赖项注入,并在每个页面上公开TestProperty。我希望能够将上面的代码放在我的_Layout.cshtml中,其中每个页面的主体都被呈现(或者其他适当的位置),因此我可以创建一个javascript变量以供每个页面使用。

我考虑过使用BaseViewModel,我的所有页面模型都是从该模型继承而来的,但是试验这个模型并没有带来任何有用的东西(只是例外)。

您如何从配置设置创建javascript属性,只能配置一次?

2 个答案:

答案 0 :(得分:4)

我提出了一些按照我需要的方式运作的东西,但是很想听听其他的建议,我的方式可能远远不是最好的..

我偶然发现了this blog post,其中讨论了MVC6关键字@inject。使用它可以将依赖项注入Razor视图。

使用此功能,我将以下内容添加到_Layout.cshtml文件的顶部:

@inject IAppSettings AppSettings; 

然后,我可以使用以下方法在此视图中引用AppSettings的属性:

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

然后我编辑了我的Startup.cs类来注册IAppSettings并创建一个AppSettings工厂,该工厂读取appsettings.json文件并在需要时创建一个新的AppSettings类:

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

这可以解决问题,我可以在我的应用程序中的任何地方访问我的javascript testProperty,但我很好奇是否有人对如何以不同的方式完成此操作有任何其他想法(可能使用BaseViewModel)?

<强>更新 根据要求,以下是有关我的实施的更多信息:

我的IAppSettingsService接口:

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

我的AppSettingsService实施:

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

AppSettings.json:

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

然后在Azure门户中,我可以随时使用AppSettings:AzureStorageAccountName更改这些值,并将值设置为“应用程序设置”部分中的所需信息。

答案 1 :(得分:1)

不确定您到底想要实现的目标。但是你所拥有的就是你在JavaScript中访问appsettings的方式。在ASP.NET Core中注入要查看的对象/服务是一件好事。

如果您只是查看不同环境的URL,您可以在发布管道中实现它。在我的日常工作中 - 我在一个web应用程序上工作,这个应用程序是asp.net core作为host + angular 2作为UI框架。我们有4个环境。角度代码总是调用我们的asp.net核心主机。我们编写了一个中间件来查找api调用并将它们转发到我们在各自环境中托管在azure上的API。 api环境的域保留为appsetting键。在我们的发布管道中 - 我们覆盖每个环境版本的属性。

最好将所有内容集中在asp.net服务器端代码中。 UI即JavaScript应该只是ping您的服务器端MVC控制器端点。这样,您可以在发布期间参数化应用程序设置。

希望这会有所帮助。