❤️ 关注 Furion 微信公众号有惊喜哦!
🫠 遇到问题了
Skip to main content
⭐️ 开通 VIP 服务仅需 499 元/年,尊享 365 天项目无忧23 立即开通23 ⭐️
特别赞助

5.2 HttpContext

📝 模块更新日志
  • 问题修复

    •   启用请求 Body 重复读且在授权之前读取导致非 GET/HEAD/OPTION 请求异常 4.8.7.15 ⏱️2023.03.19 #I6NX9E

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/IIS 无法获取正确客户端 IP 问题

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

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

// 若上面配置无效可尝试下列代码,比如在 IIS 中
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});

// 注意在 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