NET Core中怎么使用HttpContext.Current

NET Core中怎么使用HttpContext.Current

阅读目录

回到目录

一、前言

  我们都知道,ASP.NET Core作为最新的框架,在MVC5和ASP.NET WebForm的基础上做了大量的重构。如果我们想使用以前版本中的HttpContext.Current的话,目前是不可用的,因为ASP.NET Core中是并没有这个API的。

  当然我们也可以通过在Controller中访问HttpContext,但是某些情况下,这样使用起来还是不如HttpContext.Current方便。

回到目录

二、IHttpContextAccessor

  利用ASP.NET Core的依赖注入容器系统,通过请求获取IHttpContextAccessor接口,我们拥有模拟使用HttpContext.Current这样API的可能性。但是因为IHttpContextAccessor接口默认不是由依赖注入进行实例管理的。我们先要将它注册到ServiceCollection中:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
  4. // Other code...
  5. }

  来模拟一个HttpContext.Current吧:

  1. public static class HttpContext
  2. {
  3. public static IServiceProvider ServiceProvider;
  4. public static Microsoft.AspNetCore.Http.HttpContext Current
  5. {
  6. get
  7. {
  8. object factory = ServiceProvider.GetService(typeof(Microsoft.AspNetCore.Http.IHttpContextAccessor));
  9. Microsoft.AspNetCore.Http.HttpContext context = ((Microsoft.AspNetCore.Http.HttpContextAccessor)factory).HttpContext;
  10. return context;
  11. }
  12. }
  13. }

  其实说到HttpContext.Current就不得不提到多线程问题,在以前的ASP.NET版本中,如果遇到多线程环境很有可能HttpContext.Current为空的情况。说到这个问题以前就是有解决方案的,那就是CallContext;

  CallContext 是类似于方法调用的线程本地存储区的专用集合对象,并提供对每个逻辑执行线程都唯一的数据槽。数据槽不在其他逻辑线程上的调用上下文之间共享。当 CallContext 沿执行代码路径往返传播并且由该路径中的各个对象检查时,可将对象添加到其中。

  当使用ASP.NET的时候,虽然线城池里的线程是复用的,但是CallContext并不在一个线程的多次使用中共享。因为CallContext是针对逻辑线程的TLS,线程池中被复用的线程是操作系统中的内核对象而不是托管对象。就像数据库连接池中保存的是非托管资源而不是托管资源。因此,先后执行的两个托管线程可能在底层复用了一个物理线程(内核对象),但并不能共享同一组CallContext数据槽。就像先后new的两个SqlConnection对象可能在底层使用了同一个物理连接,但是托管对象的属性已经被重置。

  与此对照的是ThreadStaticAttribute,标记上这个特性的静态字段是往物理线程的TLS中保存数据(根据MSDN的描述猜的。具体没试过),因此如果两个托管线程对象内部使用的是同一个物理线程,则这个字段会复用(在两个线程通过这一字段访问同一个数据槽)。

  在.NET Core中,也有新的API选择,AsyncLocal<T>。

回到目录

三、HttpContextAccessor

  我们来看看ASP.NET Core中的IHttpContextAccessor接口实现吧:

  1. public class HttpContextAccessor : IHttpContextAccessor
  2. {
  3. #if NET451
  4. private static readonly string LogicalDataKey = "__HttpContext_Current__" + AppDomain.CurrentDomain.Id;
  5. public HttpContext HttpContext
  6. {
  7. get
  8. {
  9. var handle = CallContext.LogicalGetData(LogicalDataKey) as ObjectHandle;
  10. return handle?.Unwrap() as HttpContext;
  11. }
  12. set
  13. {
  14. CallContext.LogicalSetData(LogicalDataKey, new ObjectHandle(value));
  15. }
  16. }
  17. #elif NETSTANDARD1_3
  18. private AsyncLocal<HttpContext> _httpContextCurrent = new AsyncLocal<HttpContext>();
  19. public HttpContext HttpContext
  20. {
  21. get
  22. {
  23. return _httpContextCurrent.Value;
  24. }
  25. set
  26. {
  27. _httpContextCurrent.Value = value;
  28. }
  29. }
  30. #endif
  31. }

  最后我只能说在ASP.NET Core中是万物皆DI啊,其实Core中的实现早就为我们想好了这些功能,只是改变了使用方式。

GitHub:https://github.com/maxzhang1985/YOYOFx  如果觉还可以请Star下, 欢迎一起交流。

.NET Core 开源学习群: 214741894

时间: 2024-12-28 10:41:19

NET Core中怎么使用HttpContext.Current的相关文章

在ASP.NET Core中怎么使用HttpContext.Current

一.前言 我们都知道,ASP.NET Core作为最新的框架,在MVC5和ASP.NET WebForm的基础上做了大量的重构.如果我们想使用以前版本中的HttpContext.Current的话,目前是不可用的,因为ASP.NET Core中是并没有这个API的. 当然我们也可以通过在Controller中访问HttpContext,但是某些情况下,这样使用起来还是不如HttpContext.Current方便. 二.IHttpContextAccessor 利用ASP.NET Core的依赖

WCF 中HttpContext.Current为null的解决办法

解决WCF hosting IIS的环境中使HttpContext.Current不为NULL, 来我们传递每次请求中的Cookie 经过测试发现只要注意下面亮点就可以了: 1. 在hosting WCF的web.config中加入: <system.serviceModel>   <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/></system.serviceModel>

HttpContext.Current并非无处不在

原文地址:http://www.cnblogs.com/fish-li/archive/2013/04/06/3002940.html 阅读目录 开始 无处不在的HttpContext HttpContext.Current到底保存在哪里? HttpContext并非无处不在! 如何获取文件绝对路径? 异步调用中如何访问HttpContext? 安全地使用HttpContext.Current 了解ASP.NET的开发人员都知道它有个非常强大的对象 HttpContext,而且为了方便,ASP.

HttpContext.Current

阅读目录 开始 无处不在的HttpContext HttpContext.Current到底保存在哪里? HttpContext并非无处不在! 如何获取文件绝对路径? 异步调用中如何访问HttpContext? 安全地使用HttpContext.Current 了解ASP.NET的开发人员都知道它有个非常强大的对象 HttpContext,而且为了方便,ASP.NET还为它提供了一个静态属性HttpContext.Current来访问它, 今天的博客打算就从HttpContext.Current

在.net Core 中像以前那样的使用HttpContext.Current

今晚在学习.net Core 的使用 拿来以前项目进行改造最简单的问题就是怎么做到让httpcontext 和以前兼容 ,折腾的很久 终于搞定,纪录一下 .net core中使用了无处不在的注入,看了站长大人关于注入的文章恍然大悟.解决方法如下: 1:首先在  我们创建一个静态类 MyHttpContext public static class MyHttpContext { public static IServiceProvider ServiceProvider; static MyHt

解决Asp.net Mvc中使用异步的时候HttpContext.Current为null的方法

在项目中使用异步(async await)的时候发现一个现象,HttpContext.Current为null,导致一系列的问题. 上网查了一些资料后找到了一个对象: System.Threading.SynchronizationContext (提供在各种同步模型中传播同步上下文的基本功能.), 跟踪代码后发现 SynchronizationContext.Current 返回的是一个叫 System.Web.LegacyAspNetSynchronizationContext 的内部类对象

Asp.net中的Cache--HttpRuntim.Cache 和 HttpContext.Current.Cache

在ASP.NET中有两个类都提供缓存支持, 一个是HttpRuntime类的Cache属性, 另一个是HttpContext类的Cache属性. 通过查看这两个属性的类型可以发现其实这两个属性都是System.Web.Caching.Cache类的实例.那为什么需要同时提供两种支持呢? 查询MSDN后发先,这两个缓存的应用的场景不一样, HttpRuntime.Cache是应用程序级别的缓存, HttpContext.Current.Cache是针对Web上下文定义的, 是一个局部的缓存.(这段

ashx中应用HttpContext.Current.Session ,呈现未将对象引用设置到实例上

在ASHX一般处理程序文件中如需调用Session必须继承System.Web.SessionState.IRequiresSessionState接口,才能实现Session读写! System.Web.SessionState的接口介绍: IReadOnlySessionState 指定目标 HTTP 处理程序只需要具有对会话状态值的读访问权限.这是一个标记接口,没有任何方法. IRequiresSessionState 指定目标 HTTP 处理程序需要对会话状态值具有读写访问权.这是一个标

[掌眼]解决Castle.ActiveRecord在ASP.NET或WCF环境中HttpContext.Current无效的错误

AR設定檔要指定threadinfotype,不指定的話,預設值是用WebThreadScopeInfo,是用 HttpContext.Current.Items 來存放 SesionScope,所以碰到與UI無關的執行緒,沒有 HttpContext.Current 程式就掛啦. 解决方案一: 1.检查“web.config” <activeRecord isWeb="true" isDebug="false"> <config>... .