这是一个异常但是并没有说明引发异常的具体原因,为了让用户看到看到一些友好的异常消息,像 404 资源不存在,401没有访问权限,403资源不可用,因此我们必须启用异常处理。在ASP.NET Core里面处理异常通常在Program类中添加ExceptionHandler中间件,添加UseDeveloperExceptionPage方法来生成HTML错误信息。
app.UseDeveloperExceptionPage();我们也可以使用app.UseStatusCodePages()中间件处理响应状态码在400到599的错误,但是没有响应体,在Program.cs类中添加下面两行代码。
app.UseDeveloperExceptionPage(); app.UseStatusCodePages();在运行之前我们需要注释掉ResponseEditingMiddleware中间件。现在重新运行应用程序,输入https://localhost:7034/Game你将会看到下面错误页面:
public IActionResult Exception() { // 堆代码 duidaima.com throw new NullReferenceException(); }重新运行应用程序并且访问如下url-https://localhost:7034/-Home/Exception,你会看到更多的异常详细信息和堆栈信息
public IActionResult Error() { return View(); }接下来在Views->Home文件夹下添加一个Error的Razor视图
<h2>Some Problem</h2> <p>We got some problem, please visit back after sometime.</p>现在我们想要达到如下要求:
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视图被呈现。
{ "Key1": "Microsoft", "Key2": "Dot Net" }这里Key1和Key2是键,Microsoft和DotNet是他们的值,我们在项目文件中创建一个appsettings.json的文件,如下所示:
"Middleware": { "EnableContentMiddleware": true, "EnableShortCircuitMiddleware": true, "EnableRequestEditingMiddleware": true, "EnableResponseEditingMiddleware": false }该节点中包含了4个key,我们给每个key赋值为bool类型,在Program.cs类中读取他们的值,如果这些值为true我们将注册对应的中间件。我们可以看到EnableResponseEditingMiddleware提供的值为false剩下的全部是true,因此除了ResponseEditingMiddle-ware中间件剩余的全部注册。在Program类中我们可以使用app.Configuration()方法读取配置文件,在Programe类中添加下面代码,从appsettings读取配置并注册对应的中间件。
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 > (); }我们也可以使用GetSection和GetValue方法读取对应的值,代码如下:
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>(); }在Controller & View 中访问appsettings.json
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中提取需要的节点并将其转化为实体类,然后使用实体类访问配置文件中的键值对,整个步骤过程如下:
"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; } }现在,进入Program.cs类并且使用Configure<T>注册这个类
builder.Services.Configure<MyWebApi>(builder.Configuration.GetSection("APIEndpoints"));在Controller中引用Microsoft.Extensions.Options命名空间,在构造函数中添加IOptions<MyWebApi>依赖,现在我们可以在Controller中读取appsettings.json文件存储的值
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(); } } }在View中注入IOptions<T>
@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>一旦注入IOptions我们就可以在View中使用MyWebAPI,我们可以通过@settings.Value.PropertyName访问属性
框架会根据当前环境自动遍历appsettings的文件,如果是Development环境时使用appsettings.Development.json,如果是Production环境时使用
appsettings.Production.json首先添加一个新的文件appsettings.Production.json并且设置字串连接指向生产环境数据库
{ "ConnectionStrings": { "DefaultConnection": "Server=SQL6003.site4now.net;Database=DB_A3CE39_y11;User Id=DB_PCE39_y11_admin;Password=admin@123Ezfx;" } }接着在根目录下添加另外一个appsettings.json文件,名字为development.json,你可以在该文件中设置开发环境的连接字符串
{ "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(); } } }当应用程序运行在开发环境中会读取appsettings.Devel-opment.json的配置。