Skip to main content

5.2 HttpContext

5.2.1 关于 HttpContext

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

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

5.2.2 获取 HttpContext

ASP.NET CoreFurion 提供了多种访问 HttpContext 的方式。

5.2.2.1 在 ControllerBase 派生类中

ControllerBase 派生类中,我们可以直接通过 HttpContext 属性获取 HttpContext 对象。

public class HomeController : Controller
{
public IActionResult Index()
{
// 在这里HttpContext 是 Controller/ControllerBase 对象的属性
var httpContext = HttpContext;

return View();
}
}

5.2.2.2 注入 IHttpContextAccessor

Furion 框架中,默认已经注册了 IHttpContextAccessor 服务,所以我们可以通过构造函数注入该接口获取。

public class AppService
{
public AppService(IHttpContextAccessor httpContextAccessor)
{
var httpContext = httpContextAccessor.HttpContext;
}
}

5.2.2.3 通过 App.HttpContext

App 静态类也提供了 App.HttpContext 获取 HttpContext 对象。

var request = App.HttpContext.Request;
Web 中访问

Web 完整的生命周期内,App.HttpContext 都是有效的,但在非 Web 中返回 null,避免在多线程,事件总线,定时任务等中使用。

5.2.3 HttpContext 拓展方法

Furion 框架基于 HttpContext 提供了一些常用的拓展方法。

5.2.3.1 获取当前请求的特性 Attribute

下列代码通常用于授权 Handler 中。

var attribute = httpContext.GetMetadata<SomeAttribute>();
Middleware 中间件获取特性方式

Middleware 中间件中获取有所区别,主要通过 HttpContextFeatures 获取,如:

var endpointFeature = httpContext.Features.Get<IEndpointFeature>();
var attribute = endpointFeature?.Endpoint?.Metadata?.GetMetadata<SomeAttribute>();

5.2.3.2 设置 Swagger 自动授权

Swagger 默认不能记住授权信息,一旦刷新浏览器就自动清空,所以 Furion 提供了该拓展,即使刷新浏览器也能保持授权状态。

// 检查用户登录和生成 token 代码...
// .....

// 之后调用该拓展,这样就可以实现 Swagger 刷新也能记住登录了
httpContext.SigninToSwagger("你的token");

5.2.3.3 退出 Swagger 授权

通过后端代码强制性让 Swagger 授权实现,只针对下一次请求有效!

httpContext.SignoutToSwagger();

5.2.3.4 获取本地 IP 地址

// ipv4
var ipv4 = httpContext.GetLocalIpAddressToIPv4();

// ipv6
var ipv6 = httpContext.GetLocalIpAddressToIPv6();

5.2.3.5 获取客户端 IP 地址

// ipv4
var ipv4 = httpContext.GetRemoteIpAddressToIPv4();

// ipv6
var ipv6 = httpContext.GetRemoteIpAddressToIPv6();
Nginx 无法获取正确客户端 IP 问题

如果服务器端使用了 nginx 等反向代理工具,可添加以下代码配置:

Startup.cs
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.All;
});

// 注意在 Configure 最前面配置
app.UseForwardedHeaders();

5.2.3.6 设置响应头 Token

httpContext.SetTokensOfResponseHeaders("token", "刷新token");

5.2.4 读取 Body 内容(重复读)

版本说明

以下内容仅限 Furion 4.7.9 + 版本使用。

默认情况下,ASP.NET Core 不支持重复读取 Body 内容,Furion 框架提供了拓展方法,需要按照以下步骤操作:

  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();

5.2.5 反馈与建议

与我们交流

给 Furion 提 Issue