我正在尝试创建自己的自定义HTTP上下文:
CustomHttpContext : HttpContextBase
{
public override HttpRequestBase Request { }
}
我无法弄清楚的一件事是如何使用
初始化基类System.Web.HttpContext.Current
有没有人有任何想法我如何首先使用Current Http初始化自定义上下文然后覆盖某些方法/属性以达到我自己的目的?
答案 0 :(得分:8)
简单的答案是否定的,这是不可能的。另请注意,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管道或请求/响应处理没有任何关系。
另见:
答案 1 :(得分:0)
只需在dash的答案中添加一些内容,您也可以将[ThreadStatic]属性与一些静态属性一起使用。在BeginRequest上初始化它,可以使用global.cs,也可以编写自己的HttpModule / HttpHandler。
如何创建网络模块: http://msdn.microsoft.com/en-us/library/ms227673(v=vs.100).aspx
线程静态: http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx