一、前言
  我们都知道,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中:

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

来模拟一个HttpContext.Current吧:

namespace WebCore.Utils
{
public static class HttpContext
{
public static IServiceCollection serviceCollection; public static Microsoft.AspNetCore.Http.HttpContext Current
{
get
{
object factory = serviceCollection.BuildServiceProvider().GetService(typeof(IHttpContextAccessor));
Microsoft.AspNetCore.Http.HttpContext context = ((HttpContextAccessor)factory).HttpContext;
return context;
}
} }
}

我们看到上面HttpContext类中的public static IServiceCollection serviceCollection是没有被赋值的,所以我们还要在Startup类中的ConfigureServices中为其赋值

public void ConfigureServices(IServiceCollection services)
{
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
WebCore.Utils.HttpContext.serviceCollection = services; // Other code...
}

这样我们就可以像在以前ASP.NET中一样,在ASP.NET Core中也可以使用WebCore.Utils.HttpContext.Current了。

  其实说到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接口实现吧:

public class HttpContextAccessor : IHttpContextAccessor
{
#if NET451
private static readonly string LogicalDataKey = "__HttpContext_Current__" + AppDomain.CurrentDomain.Id; public HttpContext HttpContext
{
get
{
var handle = CallContext.LogicalGetData(LogicalDataKey) as ObjectHandle;
return handle?.Unwrap() as HttpContext;
}
set
{
CallContext.LogicalSetData(LogicalDataKey, new ObjectHandle(value));
}
} #elif NETSTANDARD1_3
private AsyncLocal<HttpContext> _httpContextCurrent = new AsyncLocal<HttpContext>();
public HttpContext HttpContext
{
get
{
return _httpContextCurrent.Value;
}
set
{
_httpContextCurrent.Value = value;
}
}
#endif
}

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

原文链接

在ASP.NET Core中怎么使用HttpContext.Current (转载)的更多相关文章

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

    一.前言 我们都知道,ASP.NET Core作为最新的框架,在MVC5和ASP.NET WebForm的基础上做了大量的重构.如果我们想使用以前版本中的HttpContext.Current的话,目 ...

  2. NET Core中怎么使用HttpContext.Current

    NET Core中怎么使用HttpContext.Current 阅读目录 一.前言 二.IHttpContextAccessor 三.HttpContextAccessor 回到目录 一.前言 我们 ...

  3. 避免在ASP.NET Core中使用服务定位器模式

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:服务定位器(Service Locator)作为一种反模式,一般情况下应该避免使用,在 ...

  4. ASP.NET Core 中 HttpContext 详解与使用 | Microsoft.AspNetCore.Http 详解 (转载)

    “传导体” HttpContext 要理解 HttpContext 是干嘛的,首先,看图 图一 内网访问程序 图二 反向代理访问程序 ASP.NET Core 程序中,Kestrel 是一个基于 li ...

  5. ASP.NET Core 中 HttpContext 详解与使用 | Microsoft.AspNetCore.Http 详解

    笔者没有学 ASP.NET,直接学 ASP.NET Core ,学完 ASP.NET Core MVC 基础后,开始学习 ASP.NET Core 的运行原理.发现应用程序有一个非常主要的 “传导体” ...

  6. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  7. Asp.net Core中使用Session

    前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Cor ...

  8. 在ASP.NET Core中使用百度在线编辑器UEditor

    在ASP.NET Core中使用百度在线编辑器UEditor 0x00 起因 最近需要一个在线编辑器,之前听人说过百度的UEditor不错,去官网下了一个.不过服务端只有ASP.NET版的,如果是为了 ...

  9. ASP.NET Core 中文文档 第三章 原理(13)管理应用程序状态

    原文:Managing Application State 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:高嵩 在 ASP.NET Core 中,有多种途径可以对应用程序的状态进行 ...

随机推荐

  1. js判断值是否是数字

    js如何判断值是否是数字 1. isNaN()方法2. 正则表达式var re = /^[0-9]+.?[0-9]*$/; //判断字符串是否为数字 //判断正整数 /^[1-9]+[0-9]*]*$ ...

  2. javascript判断一个元素是另外一个元素的子元素

    javascript判断一个元素是另外一个元素的子元素用途有很多,最常用的就是当点击页面的空白处去执行某些操作,比如弹出层等. function isParent (obj,parentObj){ w ...

  3. css 样式表集合

    说到前端不得不说一下css样式 css样式是用来装饰我们的html让整个页面显得更丰富多彩,所以我们要熟悉各种css样式,本人搜集了一下 供大家参考一下 字体属性:(font) 大小 {font-si ...

  4. Javascript 多物体运动1

    多物体运动 <!DOCTYPE html><html> <head>  <meta charset="UTF-8">  <ti ...

  5. font-size 基准

    浏览器的缺省字体为16px: 你可以先将基准字体大小设置为10px; body  { font-size: 62.5%; } 然后统一使用 em作为单位 div { font-size: 2.4em; ...

  6. vue2.0 生命周期 简析

    Vue2.0 生命周期钩子函数: <template> <div id='app'> {{message}} </div> </template> va ...

  7. vs2015使用技巧-------- 查看类关系图

    1.在项目上点击右键,点击“查看”------->“查看类图”: 2.生成的类图如下:

  8. GIT团队合作探讨之一-保持工作同步的概念和实践

    感谢英文原文作者,这是我看到的关于git协同工作写的最清晰简洁的文章了: https://www.atlassian.com/git/tutorials/syncing/git-push SVN使用一 ...

  9. 关于map容器的元素被无参初始化

    使用C++中的map容器定义一个mp,当你执行if语句判断mp[3]是否为1时,那么如果mp[3]以前不存在,此时mp[3]就会被无参初始化,second赋值为0. 以下的程序可以证明这一点.执行了第 ...

  10. python全栈学习笔记(一)网络基础之网络协议篇

    阅读目录 一.操作系统基础 二.网络通信原理 2.1 互联网的本质就是一系列的网络协议 2.2 osi七层协议 2.3 tcp/ip五层模型讲解 2.3.1 物理层 2.3.2 数据链路层 2.3.3 ...