我在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;
}
}
}
}
答案 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;
并在某处发布带有内部异常的完整异常堆栈跟踪