不确定我在这里遗漏了什么,但我无法从我的 .net 核心应用程序中的 appsettings.json 获取值。我的 appsettings.json 为:
{
"AppSettings": {
"Version": "One"
}
}
启动:
public class Startup
{
private IConfigurationRoot _configuration;
public Startup(IHostingEnvironment env)
{
_configuration = new ConfigurationBuilder()
}
public void ConfigureServices(IServiceCollection services)
{
//Here I setup to read appsettings
services.Configure<AppSettings>(_configuration.GetSection("AppSettings"));
}
}
型号:
public class AppSettings
{
public string Version{ get; set; }
}
Controller :
public class HomeController : Controller
{
private readonly AppSettings _mySettings;
public HomeController(IOptions<AppSettings> settings)
{
//This is always null
_mySettings = settings.Value;
}
}
_mySettings 始终为空。我在这里缺少什么吗?
最佳答案
ASP.NET Core 6.x 在 Program 中带来了另一个重大变化类:
Program.Main()样板文件,如果您选择使用顶级语句Startup一切都在 Program 中文件WebApplication和 WebApplicationBuilder 有人说这些变化有利于新手学习 ASP.NET Core。我有点相反的感觉。我想分开Program和 Startup更有意义,至少对我而言。
无论如何...
这就是Program.cs看起来像:
// Program.cs
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/errors");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "areaRoute",
pattern: "{area:exists}/{controller=home}/{action=index}/{id?}");
app.MapControllerRoute(
name: "default",
pattern: "{controller=home}/{action=index}/{id?}");
app.Run();
}
}
您可以说出 WebApplication.CreateBuilder() 之间的部分和 builder.Build()是什么老ConfigureServices(IServiceCollection services)以前做。和 app.Run() 之前的部分是什么老Configure()来自 Startup曾经做过。
最重要的是,IConfiguration被注入(inject)到管道中,因此您可以在 Controller 上使用它。
ASP.NET Core 3.x 带来了一些尝试支持其他方法(例如辅助服务)的更改,因此它用更通用的主机构建器替换了 Web 主机:
// Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
};
}
}
Startup不过类看起来与 2.x 版本非常相似。
你不需要新的IConfiguration在Startup构造函数。它的实现将由 DI 系统注入(inject)。
// Program.cs
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
// Startup.cs
public class Startup
{
public IHostingEnvironment HostingEnvironment { get; private set; }
public IConfiguration Configuration { get; private set; }
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
this.HostingEnvironment = env;
this.Configuration = configuration;
}
}
你需要告诉Startup加载应用程序设置文件。
// Program.cs
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
}
//Startup.cs
public class Startup
{
public IConfigurationRoot Configuration { get; private set; }
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
this.Configuration = builder.Build();
}
...
}
您可以通过多种方式从应用设置中获取您配置的值:
ConfigurationBuilder.GetValue<T> 的简单方法假设您的 appsettings.json看起来像这样:
{
"ConnectionStrings": {
...
},
"AppIdentitySettings": {
"User": {
"RequireUniqueEmail": true
},
"Password": {
"RequiredLength": 6,
"RequireLowercase": true,
"RequireUppercase": true,
"RequireDigit": true,
"RequireNonAlphanumeric": true
},
"Lockout": {
"AllowedForNewUsers": true,
"DefaultLockoutTimeSpanInMins": 30,
"MaxFailedAccessAttempts": 5
}
},
"Recaptcha": {
...
},
...
}
您可以将整个配置注入(inject)到您的 Controller /类的构造函数中(通过 IConfiguration )并使用指定的键获取您想要的值:
public class AccountController : Controller
{
private readonly IConfiguration _config;
public AccountController(IConfiguration config)
{
_config = config;
}
[AllowAnonymous]
public IActionResult ResetPassword(int userId, string code)
{
var vm = new ResetPasswordViewModel
{
PasswordRequiredLength = _config.GetValue<int>(
"AppIdentitySettings:Password:RequiredLength"),
RequireUppercase = _config.GetValue<bool>(
"AppIdentitySettings:Password:RequireUppercase")
};
return View(vm);
}
}
ConfigurationBuilder.GetValue<T>如果您只需要应用程序设置中的一个或两个值,则效果很好。但是,如果您想从应用程序设置中获取多个值,或者您不想在多个地方对这些键字符串进行硬编码,使用选项模式可能会更容易。选项模式使用类来表示层次结构/结构。
要使用选项模式:
IOptions<T>进入你想要获取值的 Controller /类的构造函数中您可以定义具有需要完全匹配应用设置中的键的属性的类。类的名称不必与应用设置中的部分名称相匹配:
public class AppIdentitySettings
{
public UserSettings User { get; set; }
public PasswordSettings Password { get; set; }
public LockoutSettings Lockout { get; set; }
}
public class UserSettings
{
public bool RequireUniqueEmail { get; set; }
}
public class PasswordSettings
{
public int RequiredLength { get; set; }
public bool RequireLowercase { get; set; }
public bool RequireUppercase { get; set; }
public bool RequireDigit { get; set; }
public bool RequireNonAlphanumeric { get; set; }
}
public class LockoutSettings
{
public bool AllowedForNewUsers { get; set; }
public int DefaultLockoutTimeSpanInMins { get; set; }
public int MaxFailedAccessAttempts { get; set; }
}
然后你需要在ConfigureServices()中注册这个配置实例在启动时:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
...
namespace DL.SO.UI.Web
{
public class Startup
{
...
public void ConfigureServices(IServiceCollection services)
{
...
var identitySettingsSection =
_configuration.GetSection("AppIdentitySettings");
services.Configure<AppIdentitySettings>(identitySettingsSection);
...
}
...
}
}
由于我在开头提到的 ASP.NET Core 6.x 的更改,您需要绑定(bind)该部分并将其添加到以下 DI:
// Program.cs
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.Configure<AppIdentitySettings>(
builder.Configuration.GetSection("AppIdentitySettings")
);
var app = builder.Build();
...
app.Run();
}
}
您可以阅读更多相关信息 here .
最后,在您想要获取值的 Controller /类上,您需要注入(inject) IOptions<AppIdentitySettings>通过构造函数:
public class AccountController : Controller
{
private readonly AppIdentitySettings _appIdentitySettings;
public AccountController(IOptions<AppIdentitySettings> appIdentitySettingsAccessor)
{
_appIdentitySettings = appIdentitySettingsAccessor.Value;
}
[AllowAnonymous]
public IActionResult ResetPassword(int userId, string code)
{
var vm = new ResetPasswordViewModel
{
PasswordRequiredLength = _appIdentitySettings.Password.RequiredLength,
RequireUppercase = _appIdentitySettings.Password.RequireUppercase
};
return View(vm);
}
}
关于c# - 从 .net 核心中的 appsettings.json 获取值(value),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46940710/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url
我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha