.NET - 静态方法中的Session对象为null

时间:2012-05-29 21:52:48

标签: .net session static

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

// 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()方法中获得一个Session。

有什么想法吗?

谢谢!

4 个答案:

答案 0 :(得分:1)

非常简单的回答:某些地方(不知道还有什么)在Session初始化之前正在点击EducationalUnit.Current。在添加条件以测试Session为null并且默默地无所事事时,错误就消失了,一切正常。

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

感谢您的反馈!

ADDENDUM:当一个Page属性间接地点击了EducationalUnit.Current时出现了这个问题:

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()

答案 1 :(得分:0)

尝试HttpContext.Current.Session

答案 2 :(得分:0)

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

此外,根据您的类被调用的链中的位置,它可能无法访问任何有用的值。通常使用静态类,让方法将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应用程序遵循特定的生命周期,并且会话可能并不总是存在,具体取决于您在生命周期中的位置....(过时。继续。)

答案 3 :(得分: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"];

        }
    }