程序与启动课程
ASP。NET Core 6.x
ASP。NET Core 6。x在Program类中带来了另一个大的变化:
如果您选择使用顶级语句,则没有Program.Main()样板
隐式使用指令
没有启动类,因为所有东西都在程序文件中
介绍WebApplication和WebApplicationBuilder
有人说,这些变化有利于新人学习ASP。净的核心。我的感觉正好相反。我认为程序和启动的分离更有意义,至少对我来说。
无论如何……
这是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服务)用来做的事情。app.Run()之前的部分是Startup中旧的Configure()所做的。
最重要的是,IConfiguration被注入到管道中,所以你可以在你的控制器上使用它。
ASP。NET Core 3。X至5
ASP。NET Core 3。X带来了一些变化,试图支持其他方法,如worker services,所以它用更通用的主机构建器取代了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版本。
ASP。NET Core 2.x
你不需要在启动构造函数中新建IConfiguration。它的实现将由DI系统注入。
// 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;
}
}
ASP。NET Core 1.x
您需要告诉Startup加载appsettings文件。
// 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": {
...
},
...
}
简单的方法
你可以将整个配置注入到你的控制器/类的构造函数中(通过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。如果你只需要应用程序设置中的一个或两个值,那么>工作得很好。但如果你想从应用程序设置中获得多个值,或者你不想在多个地方硬编码那些关键字字符串,使用选项模式可能更容易。选项模式使用类来表示层次结构/结构。
使用选项模式:
定义类来表示结构
注册这些类绑定到的配置实例
将IOptions<T>注入到你想获取值的控制器/类的构造函数中
1. 定义配置类来表示结构
你可以定义具有属性的类,这些属性需要与应用程序设置中的键完全匹配。类的名称不必与应用设置中的section名称匹配:
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; }
}
2. 注册配置实例
然后你需要在启动时在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
由于我在开头提到的ASP。NET Core 6。x,你需要绑定该section并将其添加到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();
}
}
你可以在这里阅读更多相关内容。
3.注入IOptions
最后在你想要获取值的控制器/类上,你需要通过构造函数注入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);
}
}