简单的答案是否定的,这是不可能的。另请注意,HttpContext 不是从 HttpContextBase 继承的,而是它们都实现了 IServiceProvider。最后,HttpContext 是密封的,这表明作者不希望人们做任何事情,除了消费这个类。
毫无疑问,因为 HttpContextBase 有一个无参数的构造函数,所以你甚至没有像 HttpContext 那样从当前请求和响应中实例化它的选项!
我们用一个'decompiler'来看看HttpContext.Current的实现:
// System.Web.HttpContext
/// <summary>Gets or sets the <see cref="T:System.Web.HttpContext" /> object for the current HTTP request.</summary>
/// <returns>The <see cref="T:System.Web.HttpContext" /> for the current HTTP request.</returns>
public static HttpContext Current
{
get
{
return ContextBase.Current as HttpContext;
}
set
{
ContextBase.Current = value;
}
}
如果我们看一下 ContextBase.Current(来自 System.Web.Hosting.ContextBase):
// System.Web.Hosting.ContextBase
internal static object Current
{
get
{
return CallContext.HostContext;
}
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
set
{
CallContext.HostContext = value;
}
}
和 CallContext(在 System.Runtime.Messaging 中):
// System.Runtime.Remoting.Messaging.CallContext
/// <summary>Gets or sets the host context associated with the current thread.</summary>
/// <returns>The host context associated with the current thread.</returns>
/// <exception cref="T:System.Security.SecurityException">The immediate caller does not have infrastructure permission. </exception>
public static object HostContext
{
[SecurityCritical]
get
{
IllogicalCallContext illogicalCallContext = Thread.CurrentThread.GetIllogicalCallContext();
object hostContext = illogicalCallContext.HostContext;
if (hostContext == null)
{
LogicalCallContext logicalCallContext = CallContext.GetLogicalCallContext();
hostContext = logicalCallContext.HostContext;
}
return hostContext;
}
[SecurityCritical]
set
{
if (value is ILogicalThreadAffinative)
{
IllogicalCallContext illogicalCallContext = Thread.CurrentThread.GetIllogicalCallContext();
illogicalCallContext.HostContext = null;
LogicalCallContext logicalCallContext = CallContext.GetLogicalCallContext();
logicalCallContext.HostContext = value;
return;
}
LogicalCallContext logicalCallContext2 = CallContext.GetLogicalCallContext();
logicalCallContext2.HostContext = null;
IllogicalCallContext illogicalCallContext2 = Thread.CurrentThread.GetIllogicalCallContext();
illogicalCallContext2.HostContext = value;
}
}
我们开始了解 HttpContext 是如何被检索的。它与当前用户访问网站时启动的线程打包在一起(这非常有意义!)。进一步研究我们可以看到它也会根据请求重新创建(见下文)。
我们也可以看到,在接口层,HttpContext.Current 不能更改为指向你自己的 HttpContext,因为该属性不是虚拟的。它还使用许多私有或内部的 BCL 类,因此您不能简单地复制大部分实现。
用您自己的 CustomContext 对象简单地包装 HttpContext 会更容易,也更不容易出现任何其他问题。您可以简单地将 HttpContext.Current 包装在 BaseContext 属性中,然后在类上拥有自己的属性(并使用您想要存储和检索自己的属性的任何基于会话、数据库或请求的状态存储机制)。
就个人而言,我会使用我自己的类来存储我自己的信息,因为它属于我的应用程序和用户等,并且与 http 管道或请求/响应处理没有任何关系。
另见: