1

我一直在尝试为我的一些类实现一个静态的“Current”属性,使其表现得像 HttpContext.Current 属性。那些仅依赖于上下文或请求标头的行为正常。但是,那些依赖于当前 Session 对象的失败。在这些情况下,Session 对象似乎为空:

// THIS WORKS
private static HttpContext Context { get { return HttpContext.Current; } }

// THIS APPEARS TO YIELD NULL
private static HttpSessionState Session { get { return HttpContext.Current.Session; } }

public static EducationalUnit Current
{
    get
    {
        if (Context.Items["EducationalUnit.Current"] == null)
        {
            SetCurrent();
        }
        return (EducationalUnit)Context.Items["EducationalUnit.Current"];
    }

    set
    {
        Context.Items["EducationalUnit.Current"] = value;
    }
} // Current


// I've tried a few things here, to scope out the status of the Session:
private static void SetCurrent()
{
    // shows "null"
    throw new Exception(Session);

    // shows "null"
    throw new Exception(Session.SessionID);

    // also shows "null"
    throw new Exception(HttpContext.Current.Session);

    // shows "Object reference not set to an instance of an object."
    throw new Exception(HttpContext.Current.Session.SessionID);

    // this, however, properly echos my cookie keys!
    JavaScriptSerializer js = new JavaScriptSerializer();
    throw new Exception(js.Serialize(Context.Request.Cookies.Keys.ToString()));

} // SetCurrent()

在我的一生中,我无法从 SetCurrent() 方法中获取会话。

有什么想法吗?

谢谢!

4

4 回答 4

1

非常简单的答案:在 Session 初始化之前,某个地方(不确定是什么)正在访问 EducationalUnit.Current。在添加条件以测试 Session 是否为 null 并且默默地什么都不做时,错误消失了,一切正常。

无论是什么击中 EducationalUnit.Current 可能都不需要,因为它似乎不会影响任何东西......

感谢您的反馈!

附录:当 EducationalUnit.Current 被 Page 属性间接命中时,问题就出现了:

public partial class client_configuration : System.Web.UI.Page
{
    //
    // The problem occurs here:
    //

    private Client c = Client.Current;

    //
    // Client objects refer to EducationalUnit.Current, which attempts
    // to use the Session, which doesn't exist at Page instantiation time.
    // 
    // (The assignment can safely be moved to the Page_Load event.)
    //


    protected void Page_Load(object sender, EventArgs e)
    {
        // etc.
    }
}

这是最终的(工作的)EducationalUnit 代码:

private static HttpContext Context { get { return HttpContext.Current; } }
private static HttpSessionState Session { get { return HttpContext.Current.Session; } }


public static EducationalUnit Current
{
    get
    {
        if (Context.Items["EducationalUnit.Current"] == null)
        {
            SetCurrent();
        }
        return (EducationalUnit)Context.Items["EducationalUnit.Current"];
    }

    set
    {
        Context.Items["EducationalUnit.Current"] = value;
    }
} // Current


private static void SetCurrent()
{
    if (Session == null)
    {
        throw new Exception("Session is not initialized!");
    }
    else
    {
        try
        {
            Guid EUID = new Guid(Session["classroomID"].ToString());
            Current = new EducationalUnit();
            Current.GetDetails(EUID);
        }
        catch
        {
            Current = new EducationalUnit();
        }
    }
} // SetCurrent()
于 2012-05-30T00:26:44.780 回答
0

尝试HttpContext.Current.Session

于 2012-05-29T21:57:03.180 回答
0

您的问题是,虽然 HttpContext.Current 是静态属性,但它返回的对象的属性不是。当您尝试 时private static HttpSessionState Session { get { return HttpContext.Current.Session; } },该值将填充在第一个引用上,此后永远不会更新。因此,您将获得 HttpContext.Current.Session 持有的第一个值。它保持空值,即没有引用,因此它没有对对象的引用,并且您对该属性的调用将始终返回空值。我只能告诉你不要那样做。

此外,根据您的类在链中被调用的位置,它可能无法访问任何有用的值。通常对于静态类,让方法将 HttpContext 作为参数更安全。

好的......让我们看看 Session 的实际工作原理,在幕后你所拥有的是:

    SessionStateModule  _sessionStateModule;    // if non-null, it means we have a delayed session state item

    public HttpSessionState Session { 
        get {  
            if (_sessionStateModule != null) { 
                lock (this) {  
                    if (_sessionStateModule != null) {  
                        // If it's not null, it means we have a delayed session state item 
                        _sessionStateModule.InitStateStoreItem(true);  
                        _sessionStateModule = null; 
                    } 
                } 
            }  

            return (HttpSessionState)Items[SessionStateUtility.SESSION_KEY];  
        }  
    }

    public IDictionary Items {  
        get {  
            if (_items == null) 
                _items = new Hashtable();  

            return _items; 
        } 
    }  

请注意,它在其链中的任何地方都不是静态的。Web 应用程序遵循特定的生命周期,并且会话可能并不总是存在,具体取决于您在生命周期中的哪个位置......(超时。待续。)

于 2012-05-29T22:08:07.173 回答
0

这可能与所提出的问题无关,但可能对某人有所帮助。

我有一个Generic Handler (.ashx)正在发送一些用户控件的输出,而这些用户控件又具有对象数据源,这些对象数据源是静态方法(在静态类中)。这些静态方法利用了会话对象。通过。HttpContext.Current.Session.

但是,该Session对象为空。

进一步发现,我发现当你使用通用处理程序时,如果你想访问会话对象,你必须IReadOnlySessionState在处理程序类上实现一个标记接口。作为

   public class AjaxHandler : IHttpHandler, IReadOnlySessionState
        {
         public void ProcessRequest(HttpContext context)
            {
            /* now both context.Session as well as 
    HttpContext.Current.Session will give you session values.
    */
            string str = AjaxHelpers.CustomerInfo();

            }

        }

public static class AjaxHelpers
    {
        public static string CustomerInfo()
        {
           //simplified for brevity.
return HttpContext.Current.Session["test"];

        }
    }
于 2016-12-22T09:10:21.483 回答