【问题标题】:How to initialise a custom HTTP Context or HttpContextBase如何初始化自定义 HTTP 上下文或 HttpContextBase
【发布时间】:2012-01-02 13:31:48
【问题描述】:

我正在尝试创建自己的自定义 HTTP 上下文:

CustomHttpContext : HttpContextBase
{
    public override HttpRequestBase Request { }
}

我不知道如何初始化基类

System.Web.HttpContext.Current

有没有人知道如何首先使用当前 Http 初始化自定义上下文,然后覆盖某些方法/属性以服务于我自己的目的?

【问题讨论】:

    标签: c# asp.net httpcontext


    【解决方案1】:

    简单的答案是否定的,这是不可能的。另请注意,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 管道或请求/响应处理没有任何关系。

    另见:

    【讨论】:

      【解决方案2】:

      只是为了增加一点破折号的答案,您还可以使用带有一些静态属性的 [ThreadStatic] 属性。通过使用 global.cs 或编写自己的 HttpModule/HttpHandler 在 BeginRequest 上对其进行初始化。

      如何创建网络模块: http://msdn.microsoft.com/en-us/library/ms227673(v=vs.100).aspx

      线程静态: http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-19
        • 2019-11-13
        • 1970-01-01
        • 1970-01-01
        • 2011-08-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多