分配Session变量/值时出现NullReferenceException

时间:2011-05-14 22:06:06

标签: c# .net asp.net session nullreferenceexception

我在ASP.NET项目的很多地方都使用Session变量来存储数据。我经常写这样的东西:

public uint MyPropery 
{
    get 
    {
        object o = Session["MyProperty"];
        if (o != null)
            return (uint)o;
        else
            return 0;
    }
    set 
    {
        Session["MyProperty"] = value;
    }
}

但是,这次我在setter中得到NullReferenceException。据我所知,以上述方式分配Session变量是有效的。此外,Session不为null,也不是值。

有关于此的任何想法吗?

修改

添加属性所在的UserControl的代码。我正在使用ext.net,但这不应该与此有任何关系。我想到了一个想法:

UserControl(如下所示)是在页面的代码隐藏中动态添加的。这与它有什么关系吗?

我正在添加像这样的UserControl(在页面上):

foreach(CoreCommons.System.Comment c in cg.Reply_Comments)
{
    WebApplicationExtNetTest.Secure.UserControls.CoreComment cc = new UserControls.CoreComment();
    cc._Comment = c; // here is where i get the NullRef
    this.Panel1.ContentControls.Add(cc);
}

标记:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CoreComment.ascx.cs" Inherits="WebApplicationExtNetTest.Secure.UserControls.CoreComment" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<ext:Panel runat="server" ID="CoreCommentOuterPanel" BodyStyle="background: #FFFDDE">
    <Items>
        <ext:ColumnLayout runat="server">
            <Columns>
                <ext:LayoutColumn ColumnWidth="0.8">
                    <ext:Image runat="server" ImageUrl="/Resources/bullet_triangle_green_16x16.png" Align="AbsMiddle"></ext:Image> 
                    <ext:Label runat="server" ID="lblCommentInfo"></ext:Label>
                </ext:LayoutColumn>
                <ext:LayoutColumn ColumnWidth="0.2"><ext:Button runat="server" ID="btnDelete" Icon="Delete"></ext:Button></ext:LayoutColumn>
            </Columns>
        </ext:ColumnLayout>
        <ext:Label runat="server" ID="lblComment"></ext:Label>
    </Items>
</ext:Panel>

代码隐藏:

namespace WebApplicationExtNetTest.Secure.UserControls
{
    public partial class CoreComment : System.Web.UI.UserControl
    {
        public CoreCommons.System.Comment _Comment
        {
            get
            {
                object o = Session["CoreComment_ObjectId"];
                if (o != null)
                    return (tWorks.Core.CoreCommons.System.Comment)o;
                else
                    return null;
            }
            set
            {
                Session["CoreComment_ObjectId"] = value;
                SetComment();
            }
        }            

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

        private void SetComment()
        {
            if (_Comment == null)
            {
                lblCommentInfo.Text = "";
                lblComment.Text = "";
            }
            else
            {
                lblCommentInfo.Text = _Comment.Author + ", " + _Comment.TimeStamp.ToString("g");
                lblComment.Text = _Comment.Text;
            }
        }
    }
}

3 个答案:

答案 0 :(得分:1)

我几乎完全确定在NullReferenceException中抛出了SetComment(),因为CoreComment的子控件(lblComment,lblCommentInfo)都没有在你设置的时候正确实例化_Comment财产。

这些子控件未实例化的原因确实是您当前添加CoreComment控件的方式。要动态添加UserControl,必须使用Page.LoadControl()(请参阅:here)来创建控件的新实例,因为它会执行一些幕后魔术以确保其正确初始化,其中包括儿童控件的实例化。

在旁注中,我个人将SetComment()更改为SetComment(CoreCommons.System.Comment comment)并使用参数而不是重复调用getter,或者,如果保留原始参数,至少只调用一次getter将结果存储在局部变量中。我假设可能是InProc会话存储,它不会产生太大的影响,但在任何其他存储模式下,你都会无缘无故地重新反序列化Comment对象。

答案 1 :(得分:0)

您需要使用Page.LoadControl()方法,请查看here

BTW :问题在于以这种方式以编程方式添加控件。

答案 2 :(得分:0)

使用:

return Session["MyProperty"] as uint? ?? 0;

并在某处发布带有内部异常的完整异常堆栈跟踪