.Net Core 2.1 - 在javascript文件中读取appsettings.json

7
我有一个使用SignalR的.NET Core 2.1 Web应用程序。我需要将HubUrl传递到自定义的JavaScript文件中。在.NET Core中是否可能实现这个?
以下是JavaScript代码示例:
const connection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:5000/hub') //Here I need to read appSettings.json to get value from there
.configureLogging(signalR.LogLevel.Information)
.build();

如果您的JavaScript位于视图中,并且您正在使用某种视图引擎(如Razor),您可以查看此帖子以获取解决方案:https://dev59.com/clUM5IYBdhLWcg3wWvHF。 - maximelian1986
@maximelian1986 问题在于我只是在视图中像这样引用了这个Js文件 `<script src="~/lib/signalr/signalr.js"></script><script src="~/js/signalrCustom.js"></script>`。 - k1dl3r
5个回答

10

appsettings.json位于服务器上。因此,您需要向控制器添加端点以返回所需值。

控制器:

public class MyController:Controller{
    private readonly IConfiguration configuration;

    public MyController(IConfiguration configuration){
         this.configuration = configuration;
    }

    [HTTPGet]
    public ActionResult GetConfigurationValue(string sectionName, string paramName){
        var parameterValue= configuration[$"{sectionName}:{paramName}"];
        return Json(new { parameter= parameterValue});
    }
}

客户端代码:

$.ajax({
    type:"GET",
    url: "/MyController/GetConfigurationValue"
    data:{
        sectionName = "MySection",
        paramName = "MyParameter"
    }
}).done(
    function(parameterValue){
        //do what you need
});
在 appsettings.json 文件中:
{
    "MySection":{
        "MyParameter":"value that I want to get"
    }
}

1
运行得非常好。非常感谢。 - k1dl3r
6
请注意,这个实现非常危险,因为它允许任何人读取任何配置值,包括像连接字符串或其他内部值这样的秘密信息。如果你想要有一个返回配置值的端点,你应该限制只有极少数的明确值可以访问和/或有非常强的输入验证来防止人们访问关键信息。 - poke
每次读取设置值时,都会触发此控制器。尝试将所有配置值作为列表提取出来。确保您的密钥得到妥善管理。 - Kurkula
@Kurkula,这个实现只运行一次。它会向控制器发出AJAX调用,然后在AJAX调用完成时执行一个函数,该函数可能会对parameterValue的值进行操作。但是,我同意您的观点,最好将控制器实现为以列表形式提取所有所需的配置值,以便每个页面视图仅访问一次控制器。在当前形式下,当您需要多个配置值时,AJAX调用无法重复使用,但这不是OP问题的一部分。 - Blair Allen

9
appsettings.json 文件中。
"ApiUrls": {
    "commonUrl": "https://localhost:44348/api/"    
  }

_Layout.cshtml中。
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<script>      
        const commonUrl = @Json.Serialize(@Configuration.GetSection("ApiUrls").GetSection("commonUrl").Value)
</script>

现在这将是一个全局变量,可被所有的JS文件访问。


3
一个非常安全但灵活的方法是将URL放在视图内的<script>块中公开。这样,您不会暴露应用程序配置(需要非常好地保护的访问权限),而只是明确地公开单个安全值。
它还具有额外的好处,即您无需发出到端点的请求(您实际上也需要知道其地址),而是在需要时立即拥有该值。
为此,您可以简单地呈现定义全局值的<script>标记。例如,您可以在布局中拥有以下内容:
<script>
window._signalRAddress = @Json.Serialize(ViewData["SignalRAddress"]);
</script>
<script src="~/your-custom-script.js"></script>

然后您只需要在脚本中使用window._signalRAddress


1
我相信这是一个更好的解决方案。 - itminus
我在我的几个Web应用程序中使用这种方法。然而,最近在使用内容安全策略(CSP)有效地列出可以由浏览器执行的脚本时遇到了问题。有了CSP脚本策略,我需要添加“'unsafe-inline'”作为异常,从而允许执行任何内联脚本,包括可能被恶意注入的内容。(因此该策略被命名为“不安全”)。如果您开始采用CSP,请注意这一点! - Blair Allen
@BlairAllen 这适用于任何类型的内联脚本。或者,您也可以有一个控制器操作,例如返回动态呈现的JavaScript文件。 - poke

1
在使用webpack的单页应用中,您可以导入appsettings.json,并通过导入方便类使其可用;例如:

appsettings.js:

appsettingsjson = process.env.NODE_ENV === 'development'
    ? require('./appsettings.Development.json')
    : require('./appsettings.json');

class AppConfig {

    constructor() {
    }

    static Settings() {
        return appsettingsjson;
    }
}

module.exports = AppConfig;

然后无论在哪里需要它,只需导入并使用。例如:

const AppConfig = require("./appsettings");
console.log(AppConfig.Settings().YourSection.YourParameter)

0
尊重“Maxemelian”的回答,通过添加验证用例来扩展答案
  1. 如果部分名称为空
  2. 忽略密码
private readonly IConfiguration configuration;

public MyController(IConfiguration configuration){
     this.configuration = configuration;
}

[HttpGet("[action]")]
public ActionResult GetConfigurationValue(string sectionName, string paramName)
{
    if (paramName.ToLower().Contains("secret")) {
        return null;
    }

    var parameterValue = (!string.IsNullOrEmpty(sectionName)) ? config[$"{sectionName}:{paramName}"] : config[$"{paramName}"];
    return Json(new { parameter = parameterValue });
}

我建议您的控制器拒绝(返回null)所有参数名称,除了您列入白名单的参数名称。如果您当前的实现中将 secret2 添加到配置文件中但忘记更新此控制器代码,则会意外公开该新秘密值。 - Blair Allen

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