关于 HttpContext #
关于 HttpContext #
 在 ASP.NET 的时代,我们通常通过 HttpContext 全局静态类获取请求上下文,但在 ASP.NET Core 中,HttpContext 是一个非静态的抽象类,无法手动创建,也无法通过静态获取。
虽然在 ASP.NET Core 中无法直接获取 HttpContext 对象。但是微软也提供了注入 IHttpContextAccessor 方式获取。
获取 HttpContext #
 ASP.NET Core 和 Mall3s 提供了多种访问 HttpContext 的方式。
在 ControllerBase 派生类中 #
 在 ControllerBase 派生类中,我们可以直接通过 HttpContext 属性获取 HttpContext 对象。
public class HomeController : Controller
{
    public IActionResult Index()
    {
        // 在这里HttpContext 是 Controller/ControllerBase 对象的属性
        var httpContext = HttpContext;
        return View();
    }
}
注入 IHttpContextAccessor #
 在 Mall3s 框架中,默认已经注册了 IHttpContextAccessor 服务,所以我们可以通过构造函数注入该接口获取。
public class AppService
{
    public AppService(IHttpContextAccessor httpContextAccessor)
    {
        var httpContext = httpContextAccessor.HttpContext;
    }
}
通过 App.HttpContext #
 App 静态类也提供了 App.HttpContext 获取 HttpContext 对象。
var request = App.HttpContext.Request;
非 `Web` 中访问
在 Web 完整的生命周期内,App.HttpContext 都是有效的,但在非 Web 中返回 null,避免在多线程,事件总线,定时任务等中使用。
HttpContext 拓展方法 #
 Mall3s 框架基于 HttpContext 提供了一些常用的拓展方法。
获取当前请求的特性 Attribute #
 下列代码通常用于授权 Handler 中。
var attribute = httpContext.GetMetadata<SomeAttribute>();
`Middleware` 中间件获取特性方式
在 Middleware 中间件中获取有所区别,主要通过 HttpContext 的 Features 获取,如:
var endpointFeature = httpContext.Features.Get<IEndpointFeature>();
var attribute =  endpointFeature?.Endpoint?.Metadata?.GetMetadata<SomeAttribute>();
设置 Swagger 自动授权 #
 Swagger 默认不能记住授权信息,一旦刷新浏览器就自动清空,所以 Mall3s 提供了该拓展,即使刷新浏览器也能保持授权状态。
// 检查用户登录和生成 token 代码...
// .....
// 之后调用该拓展,这样就可以实现 Swagger 刷新也能记住登录了
httpContext.SigninToSwagger("你的token");
退出 Swagger 授权 #
 通过后端代码强制性让 Swagger 授权实现,只针对下一次请求有效!
httpContext.SignoutToSwagger();
获取本地 IP 地址 #
// ipv4
var ipv4 = httpContext.GetLocalIpAddressToIPv4();
// ipv6
var ipv6 = httpContext.GetLocalIpAddressToIPv6();
获取客户端 IP 地址 #
// ipv4
var ipv4 = httpContext.GetRemoteIpAddressToIPv4();
// ipv6
var ipv6 = httpContext.GetRemoteIpAddressToIPv6();
`Nginx` 无法获取正确客户端 `IP` 问题
如果服务器端使用了 nginx 等反向代理工具,可添加以下代码配置:
services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.All;
});
// 注意在 Configure 最前面配置
app.UseForwardedHeaders();
设置响应头 Token #
 httpContext.SetTokensOfResponseHeaders("token", "刷新token");
读取 Body 内容(重复读) #
 版本说明
以下内容仅限 Mall3s 4.7.9 + 版本使用。
默认情况下,ASP.NET Core 不支持重复读取 Body 内容,Mall3s 框架提供了拓展方法,需要按照以下步骤操作:
- 在 Startup.cs的Configure启用Body重复读功能:
- .NET5版本:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ...
    app.EnableBuffering();
    app.UseRouting();
    // ....
}
- .NET6+版本:
var builder = WebApplication.CreateBuilder(args).Inject();
// ...
var app = builder.Build();
// ...
app.UseInject();
app.EnableBuffering();
app.MapControllers();
app.Run();
注意:app.EnableBuffering() 必须在 app.UseRouting() 或 app.MapControllers() 之前注册。
- 使用 HttpContext或HttpRequest拓展.ReadBodyContentAsync()即可。
// HttpContext 拓展
var body = await httpContext.ReadBodyContentAsync();
// HttpRequest 拓展
var body = await httpContext.Request.ReadBodyContentAsync();
