【问题标题】:NullReferenceException when assigning a Session variable/value分配会话变量/值时出现 NullReferenceException
【发布时间】:2021-01-06 16:50:52
【问题描述】:

我在 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 不为空,value 也不为空。

对此有什么想法吗?

编辑:

为该属性所在的 UserControl 添加代码。我正在使用 ext.net,但这应该与此无关。我脑海中闪过一个念头:

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;
            }
        }
    }
}

【问题讨论】:

  • 您发布的代码看起来应该可以工作。您能否发布失败的实际示例?
  • 我一直使用相同的模式没有问题。我说问题出在其他地方。您可以在会话不存在时设置值
  • @SirViver:它有很多代码,是项目的一部分。它在一个 UserControl 中,我已经更新了帖子并发布了整个 UserControl。
  • @Jeff:会话必须存在,因为我已登录该站点。嗯……
  • 正如我在更新后的帖子中所写:问题是否与我动态添加这些控件的事实有关?

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


【解决方案1】:

我几乎完全确定NullReferenceException 被抛出在SetComment() 中,因为CoreComment 的子控件(lblComment、lblCommentInfo)都没有在您设置_Comment 属性时被正确实例化。

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

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

【讨论】:

  • 谢谢。有人告诉我,使用构造函数与使用 LoadControl 一样好。我第一次尝试使用 LoadControl,但遇到了另一个(不相关的)错误,所以我转而使用构造函数。正如您所说,使用构造函数似乎并不能很好地实例化控件。现在,由于某种原因,LoadControl 有效,当我使用它时,该属性的设置也有效。谢谢 =)
  • 请注意:我尚未确认您关于 SetComment 中的错误的第一句话。虽然它不太可能,因为它在 SetComment 之前中断。
【解决方案2】:

你需要改用Page.LoadControl()方法,请看here

顺便说一句:问题在于以这种方式以编程方式添加控件。

【讨论】:

  • 确实如此。查看我对 SirViver 的评论 =)
【解决方案3】:

用途:

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

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

【讨论】:

    猜你喜欢
    • 2018-07-05
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 2018-09-07
    • 1970-01-01
    相关资源
    最近更新 更多