文章目录
UseDeveloperExceptionPage中间件
打开再Startup类的Configure()方法,并修改为以下👇代码。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseFileServer();
app.Run(async (context) =>
{
throw new Exception("读者的请在管道中发生了一些异常,请检查");
await context.Response.WriteAsync("Hello World");
});
}
我们使用上面👆的代码运行程序后看不到异常,而会看到来自default.html页面的内容👉"读者好,我是default.html"。
如果了解ASP.NET Core请求处理管道的工作原理,那么读者可能已经知道我们没有看到异常的原因。UseFileServer()中间件结合了UseDefaultFiles()和UseStaticFiles()中间件的功能。wwwroot文件夹中包含了一个名为default.html的默认HTML文件。
因此,对应用程序根节点的URL的请求,即http://localhost:2875 (读者计算机上的端口号和这里可能不同),由UseFileServer()中间件处理并且在管道中进行了反向传递。因此,在请求处理管道中我们注册的Run()方法作为下一个中间件也无法执行,导致我们不会看到此中间件抛出的异常。
现在,如果我们向http://localhost:2875/abc.html 发出请求,则会看到异常。因为在这种情况下,UseFileServer()中间件找不到名为abc.html
的文件。它会继续调用管道的下一个中间件,在这里我们使用Run()方法注册中间件。此中间件抛出异常,我们按预期看到异常详细信息。
如果读者对传统的ASP.NET开发有一定的经验,那么必定对此页面非常熟悉,上图所示的页面类似于传统ASP.NET中的黄色死亡页面。
此页面包含了异常的详细信息。
- 堆栈追踪,包括导致异常的文件名和行号。
- 查询字符串、Cookies、HTTP Header以及路由。
当读者点击异常页面的Query选项卡时,发现请求URL没有任何的查询字符串参数。如果我们请求URL中有字符串查询参数,读者将在Query选项卡看到它们。例如,我这里添加的查询字符串是username=sa&password=123
。
自定义UseDeveloperExceptionPage中间件
与ASP.NET Core中的其他大多数中间件一样,我们也可以自定义UseDeveloperExpectionpage()中间件。每当想要自定义中间件时,请始终记住读者可能拥有相应的Options对象。要自定义UseDeveloperExceptionPage()中间件,代码如下:
DeveloperExceptionPageOptions developerExceptionPageOptions = new DeveloperExceptionPageOptions { SourceCodeLineCount = 3 };
app.UseDeveloperExceptionPage(developerExceptionPageOptions);
SouceCodeLineCount属性值确定显示引发异常代码的上方和下方的代码行数。如图显示的是我们将其设置为3行后显示的代码。
UseDeveloperExceptionPage中间件如何工作
UseDeveloperExceptionPage()中间件的位置应尽可能地放在其他中间件地前面,因为如果管道后面的中间件引发异常,它可以处理异常并显示开发异常页面。
请参考以下代码,在使用Run()方法注册的中间件后,再注册UseDeveloperExceptionPage()中间件。那么,在这种情况下将不会显示开发异常页面。这就是它必须尽早放置在请求处理管道的原因。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//app.UseFileServer();
app.Run(async (context) =>
{
throw new Exception("读者的请求管道中发生了一些异常,请检查");
await context.Response.WriteAsync("Hello World");
});
if (env.IsDevelopment())
{
DeveloperExceptionPageOptions developerExceptionPageOptions = new DeveloperExceptionPageOptions { SourceCodeLineCount = 3 };
app.UseDeveloperExceptionPage(developerExceptionPageOptions);
}
}
ASP.NET Core中的环境变量配置
接下来,我们学习如何在ASP.NET Core中配置环境变量。在软件公司中会有不同的软件开发环境,通常包含以下3中。
- 开发环境(Development)。
- 演示(模拟、临时)环境(Staging)。
- 生产环境(Production)。
那么就产生一个疑问❓,为什么我们需要这些不同的开发环境呢❓
开发环境(Development):软件开发人员通常将此环境用于日常开发工作中。我们希望在开发环境中加载没有压缩过的Javascript和CSS文件,以便于测试。类似地,如果存在未处理的异常,则需要开发异常界面,以便于开发人员可以理解异常的根本原因并在需要时进行恢复。
演示环境(Staging):许多组织或者公司尝试使其演示环境尽可能与实际生产环境一致。此环境的主要目的是识别任何与部署相关的问题。此外,如果读者正在开发B2B(企业对企业)应用程序,则可能正在与其他服务提供商系统连接,如支付宝、微信支付和银行系统等。许多公司通常会设置其演示环境与服务提供商进行交互,以进行完整的端到端测试。
我们通常不会在演示环境中进行故障排除和调试,为了获得良好的性能,我们需要记载压缩过的Javascript和CSS文件。如果存在未处理的异常,则显示用户友好的错误页面而不是开发异常页面。用户友好的错误页面不包含任何技术细节,它一般包含如下信息:“出现错误,请使用下面的联系方式发送电子邮件或者通过QQ联系我们获得应用程序支持”。
生产环境(Production):它用于日常业务的实际环境。生产环境中会配置很多信息以获得更好的安全性和性能,因此,它会加载压缩后的Javascript和CSS文件以优化性能。为了更好的安全性,会显示用户友好的错误页面而不是开发异常页面。开发异常页面上的技术细节对最终用户没有意义,反而可能会造成恶意用户使用它们入侵读者的应用程序。
不同公司的环境变量配置往往不尽相同,比如大型互联网公司会采用开发环境(Development)、测试环境(Testing)、预发布环境(UAT)和正式环境(Production)等方式进行定义。
配置ASPNETCORE_ENVIRONMENT变量
使用此变量为应用程序设置环境。在本地开发计算机上,通常在launchsettings.json
文件中设置此环境变量。如果有需要,也可以在操作系统中设置。在Windows操作系统上的设置如下。
- 打开Windows控制面板,可以在运行窗口输入“Control”快速进入。
- 在环境控制面板窗口右上角的文本框中输入“环境”。
- 单击编辑系统环境变量。
- 在弹出的系统属性窗口中单击环境变量。
- 在弹出的环境变量窗口中,单击系统变量部分下的新建按钮。
- 在弹出的新建系统变量对话框中,在变量名文本框中输入值“ASPNETCORE_ENVIRONMENT”,在变量值文本框中输入
Development
。
- 单击确定按钮关闭所有弹出的窗口。
要打开系统属性窗口,还可以 在桌面上右击我的电脑(此电脑💻)➡属性➡在控制面板主页一栏 选择高级系统设置,即可打开系统属性窗口。
在Staging或Production环境中,我们通常在操作系统中设置此环境变量。我们通常将此变量设置为以下值之一,具体设置取决于托管和运行应用程序的环境。
- Development。
- Staging。
- Production。
现在已经将本地计算机的环境设置为Development,即开发环境。
访问ASPNETCORE _ENVIRONMENT变量值
ASP.NET Core提供了”开箱即用“的IWebHostEnvironment
服务,我们可以使用它来访问ASPNETCORE_ENVIRONMENT变量值。
回到我们一致使用的示例应用程序,注意Startup.cs
文件中的Configure()
方法,IWebHostEnvironment
服务已经在项目创建的时候就注入此方法。现在修改Configure()
方法中的代码,如下所示。(注意,我们使用IWebHostEnvironment
服务的EnvironmentName
属性来访问环境名称)。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//使用纯静态文件支持的中间件,而不是用终端中间件
app.UseStaticFiles();
app.Run(async (context) =>
{
//返回当前的环境变量
await context.Response.WriteAsync("Hosting Environment:"+env.EnvironmentName);
});
}
现在删除launchsettings.json
文件中的ASPNETCORE_ENVIRONMENT
键值对,代码如下。
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
}
运行此项目,访问http://localhost:2875 ,返回如图所示的结果。
请注意,如果读者的返回值是Production,则说明操作系统设置的环境变量没有生效,请重新启动一次Visual Studio试一试。
如果在两个位置launchsettings.json
文件中和操作系统中都设置了环境变量,则launchsettings.json
文件中的值将覆盖操作系统级别指定的值;如果没有明确设置ASPNETCORE_ENVIRONMENT
变量,则其值默认为Production
,这么做是为了更好的性能和安全性。
想象一下,在生产服务器上没有将ASPNETCORE_ENVIRONENT
变量值设置为Production。如果默认值是Development
,则应用程序可能会显示Developer Exception Page,并且恶意用户可能利用它来入侵应用程序。
此外,它加载未压缩的文件,而不是加载压缩过的Javascript和CSS文件。因此,为了获得更好的性能和安全性,如果不明确设置ASPNETCORE_ENVIRONENT
变量,则其值默认为Production
。
现在读者可以将本地计算机的环境变量设置删除,它的默认值即Production
,记得重启Visual Studio。
IWebHostEnvironment服务中的常用方法
我们使用IWebHostEnvironment
服务内置的以下方法来标识运行应用程序的环境。
- IsDevelopment()。
- IsStaging()。
- IsProduction()。
如果读者拥有用户验收测试(UAT)环境或质量保证(QA)环境等自定义环境,该怎么办?
注意,自定义环境包括开发环境(Development)、集成环境(Integration)、测试环境(Testing)、QA验证、模拟环境(Staging)和生产环境(Production)。
ASP.NET Core也支持这些自定义环境。比如,要检查环境是否为UAT,请使用IsEnvironment()
方法,如下所示。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//如果环境是Development 则显示开发人员异常页面
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//否则显示用户友好的错误页面
else if (env.IsStaging() || env.IsProduction() || env.IsEnvironment("UAT"))
{
app.UseExceptionHandler("/Error");
}
//其他代码
});
}
总结😀
关于UseDeveloperExceptionPage()中间件,需要了解以下内容。
-
在管道中通过UseDeveloperExceptionPage()启用中间件,必须尽可能地提早在管道中注入。
-
异常详情页面会展示包含Stack、Query、Cookies、Headers和Routing的内容。
-
如果需要自定义异常页面,则可以使用DeveloperExceptionPageOptions对象。
关于开发环境变量,需要了解以下内容。
-
ASPNETCORE_ENVIRONMENT变量可以设置在运行时环境(Runtime Environment)。
-
在开发者计算机的launchsettings.json文件中设置环境变量。
-
尽量在操作系统中设置Staging或者Production的变量。
-
可使用IWebHostEnvironment服务访问运行时环境,除内置的(Development、Staging和Production)环境之外,还支持自定义环境(UAT和QA等)。
-
关于环境变量,其实ASP.NET Core还提供了一个Environment TagHelper,它能根据程序中ASPNETCORE_ENVIRONMENT变量的值呈现不同的内容。
我们在以后部署生产环境的时候要做好开发环境的区分,养好良好的习惯。