我们使用了空模版来创建应用程序,为了获取应用程序异常我们需要添加处理异常的中间件
运行应用程序,浏览器中输入https://localhost:7034/game浏览器将输入No Response Generated.
app.UseDeveloperExceptionPage();
我们也可以使用app.UseStatusCodePages()中间件处理响应状态码在400到599的错误,但是没有响应体,在Program.cs类中添加下面两行代码
app.UseDeveloperExceptionPage();
app.UseStatusCodePages();
在运行之前我们需要注释掉ResponseEditingMiddleware中间件
现在重新运行应用程序,输入https://localhost:7034/Game你将会看到下面错误页面:
我们在HomeController内添加一个Exception方法,这个方法抛出NullReferenceException一个
public IActionResult Exception()
{
throw new NullReferenceException();
}
public IActionResult Error()
{
return View();
}
接下来在Views->Home文件夹下添加一个Error的Razor视图
<h2>Some Problem</h2>
<p>We got some problem, please visit back after sometime.</p>
我们现在更新一下Program.cs类
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days.
app.UseHsts();
}
else
{
app.UseDeveloperExceptionPage();
app.UseStatusCodePages();
}
UseExceptionHandler中间件捕获ASP.NET Core应用程序发生的异常,app.UseExceptionHandler("/Home/Error")设置错误路径为/Home/Error,如果发生错误,会调转到该action
为了测试,设置ASPNETCORE_ENVIRONMENT为Production,运行应用程序并访问/Home/Exception页面,这次你将会看到Error视图被呈现
appsettings.json包含数据库链接的键值对,全局变量和另外一些ASP.NET Core应用程序的配置,appsettings.json 文件位于应用程序的根目录下,文件的内容如下:
{
"Key1": "Microsoft",
"Key2": "Dot Net"
}
"Middleware": {
"EnableContentMiddleware": true,
"EnableShortCircuitMiddleware": true,
"EnableRequestEditingMiddleware": true,
"EnableResponseEditingMiddleware": false
}
该节点中包含了4个key,我们给每个key赋值为bool类型,在Program.cs类中读取他们的值,如果这些值为true我们将注册对应的中间件
if (Convert.ToBoolean(app.Configuration["Middleware:EnableResponseEditingMiddleware"]))
{
app.UseMiddleware<ResponseEditingMiddleware>();
}
if (Convert.ToBoolean(app.Configuration["Middleware:EnableRequestEditingMiddleware"]))
{
app.UseMiddleware<RequestEditingMiddleware>();
}
if (Convert.ToBoolean(app.Configuration["Middleware:EnableShortCircuitMiddleware"]))
{
app.UseMiddleware<ShortCircuitMiddleware>();
}
if (Convert.ToBoolean(app.Configuration["Middleware:EnableContentMiddleware"]))
{
app.UseMiddleware<ContentMiddleware>();
}
if ((app.Configuration.GetSection("Middleware")?.GetValue<bool>("EnableResponseEditingMiddleware")).Value)
{
app.UseMiddleware<ResponseEditingMiddleware>();
}
if ((app.Configuration.GetSection("Middleware")?.GetValue<bool>("EnableRequestEditingMiddleware")).Value)
{
app.UseMiddleware<RequestEditingMiddleware>();
}
if ((app.Configuration.GetSection("Middleware")?.GetValue<bool>("EnableShortCircuitMiddleware")).Value)
{
app.UseMiddleware<ShortCircuitMiddleware>();
}
if ((app.Configuration.GetSection("Middleware")?.GetValue<bool>("EnableContentMiddleware")).Value)
{
app.UseMiddleware<ContentMiddleware>();
}
public class SomeController : Controller
{
private IWebHostEnvironment _env;
private IConfiguration _config;
public SomeController(IWebHostEnvironment hostingEnvironment, IConfiguration configuration)
{
_env = hostingEnvironment;
_config = configuration;
}
public IActionResult Index()
{
bool contentMiddleware = Convert.ToBoolean(_config["Middleware:EnableContentMiddleware"]);
return View();
}
}
在大型项目中,在appsettings.json中可能有上百个实体类,这种情况下比较好的方法是从appsettings.json中提取需要的节点并将其转化为实体类,然后使用实体类访问配置文件中的键值对,整个步骤过程如下:
1 创建一个类包含appsettings.json节点
因此,在appsettings.json添加新的节点包含API相关的信息,在Controller中只使用这个API相关的节点
"Middleware": {
"EnableContentMiddleware": true,
"EnableShortCircuitMiddleware": true,
"EnableRequestEditingMiddleware": true,
"EnableResponseEditingMiddleware": false
},
"APIEndpoints": {
"Name": "OpenWeatherMap",
"Url": "http://api.openweathermap.org/",
"IsSecured": true
}
现在创建一个类包含APIEndpoints节点下Key的值,你必须保证这个类的属性和section内部节点的名字是一样的,我们在Models文件夹下创建一个MyWebApi.cs类
public class MyWebApi
{
public string Name { get; set; }
public string Url { get; set; }
public bool IsSecured { get; set; }
}
builder.Services.Configure<MyWebApi>(builder.Configuration.GetSection("APIEndpoints"));
using AspNetCore.Configuration.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace AspNetCore.Configuration.Controllers
{
public class ReadController : Controller
{
private readonly IOptions<MyWebApi> _options;
public ReadController(IOptions<MyWebApi> options)
{
_options = options;
}
public IActionResult Index()
{
var apiName=_options.Value.Name;
var url=_options.Value.Url;
var secured=_options.Value.IsSecured;
return View();
}
}
}
12.3 在View中注入IOptions<T>
我们可以使用下面指令在View中注入IOptions<MyWebApi>
@using Microsoft.Extensions.Options;
@using AspNetCore.Configuration.Models;
@inject IOptions<MyWebApi> settings;
<p>@settings.Value.Name</p>
<p>@settings.Value.Url</p>
<p>@settings.Value.IsSecured</p>
我们可以通过创建2个新的appsettings文件来做这个功能,第一个文件的名字为appsettings.Production.json,第二个文件的名字为appsettings.Development.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=SQL6003.site4now.net;Database=DB_A3CE39_y11;User Id=DB_PCE39_y11_admin;Password=admin@123Ezfx;"
}
}
{
"ConnectionStrings": {
"DefaultConnection": "Server=vaio;Database=Goldentaurus;Trusted_Connection=True;"
}
}
新添加的文件在解决方案中被隐藏起来,你可以右击appsettings.json文件前面的箭头可以查看到这两个文件
如下图所示:
builder.Services.Configure<Connections>(builder.Configuration.GetSection("ConnectionStrings"));
下一步,创建Connections.cs类将包含连接字符串:
public class Connections
{
public string DefaultConnection { get; set; }
}
接着在控制器的构造函数中添加IOptions<Connections>的依赖,可以获取数据库字符串连接
using AspNetCore.Configuration.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace AspNetCore.Configuration.Controllers
{
public class ConnectionController : Controller
{
private IOptions<Connections> _options;
public ConnectionController(IOptions<Connections> options)
{
_options = options;
}
public IActionResult Index()
{
var connections = _options.Value.DefaultConnection;
return View();
}
}
}
总结
我们通过五篇文章来从不同角度分析了ASP.NET Core配置
1 .csproj 文件
2. Kestrel Server
3. Program 类
4. ASP.NET Core 服务
5. ASP.NET Core 中间件
6. ASP.NET Core 宿主环境变量
7. 生产和开发环境异常处理
8. appsettings.json 文件在开发和测试环境应用以及读取