关于 HttpContext #

关于 HttpContext #

ASP.NET 的时代,我们通常通过 HttpContext 全局静态类获取请求上下文,但在 ASP.NET Core 中,HttpContext 是一个非静态的抽象类,无法手动创建,也无法通过静态获取。

虽然在 ASP.NET Core 中无法直接获取 HttpContext 对象。但是微软也提供了注入 IHttpContextAccessor 方式获取。

获取 HttpContext #

ASP.NET CoreMall3s 提供了多种访问 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 中间件中获取有所区别,主要通过 HttpContextFeatures 获取,如:

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 框架提供了拓展方法,需要按照以下步骤操作:

  1. Startup.csConfigure 启用 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() 之前注册。

  1. 使用 HttpContextHttpRequest 拓展 .ReadBodyContentAsync() 即可
// HttpContext 拓展
var body = await httpContext.ReadBodyContentAsync();

// HttpRequest 拓展
var body = await httpContext.Request.ReadBodyContentAsync();
上次更新: 3/10/2023, 5:09:25 PM