分配会话变量/值时出现 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,value 也不为 null。
对此有什么想法吗?
编辑:
添加该属性所在的 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;
}
}
}
}
I have in many places in my ASP.NET project used the Session variable for storing data. I usually write something like this:
public uint MyPropery
{
get
{
object o = Session["MyProperty"];
if (o != null)
return (uint)o;
else
return 0;
}
set
{
Session["MyProperty"] = value;
}
}
However, this time I get a NullReferenceException in the setter. As far as I know, it is valid to assign the Session variable in the manner above. Also, Session is not null and neither is value.
Any ideas on this?
Edit:
Adding the code for the UserControl in which the property exists. I am using ext.net but that shouldn't have anything to do with this. One thought that crossed my mind:
The UserControl (seen below) is added dynamically in code-behind of a page. Can that have anything to do with it?
I am adding UserControls like this (on a Page):
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);
}
Markup:
<%@ 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>
Code-behind:
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;
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我几乎完全确定
SetComment()
中抛出了NullReferenceException
,因为CoreComment
的子控件(lblComment、lblCommentInfo)都没有被抛出。在您设置_Comment
属性时正确实例化。这些子控件未实例化的原因确实是您当前添加 CoreComment 控件的方式。要动态添加 UserControl,您必须使用
Page.LoadControl()
(请参阅:此处)创建控件的新实例,因为它执行一些幕后魔法以确保其正确初始化,其中包括子控件的实例化。顺便说一句,我个人会将
SetComment()
更改为SetComment(CoreCommons.System.Comment comment)
并使用参数而不是重复调用 getter,或者,如果保持原来的样子,至少只调用一次 getter 并将结果存储在局部变量中。对于我认为可能是 InProc 会话存储的情况,它不会产生太大的差异,但在任何其他存储模式下,您都会无缘无故地重复反序列化Comment
对象。I'm almost completely sure the
NullReferenceException
is thrown inSetComment()
because none of theCoreComment
's child controls (lblComment, lblCommentInfo) are properly instantiated at the point you set the_Comment
property.The reason these child controls are not instantiated is indeed the way you currently add the
CoreComment
controls. For dynamically adding UserControls, you must usePage.LoadControl()
(see: here) to create a new instance of the control, as it does some behind-the-scenes magic to ensure it is properly initialized, which includes the instantiation of the child controls.On a sidenote, personally I'd change
SetComment()
toSetComment(CoreCommons.System.Comment comment)
and use the parameter instead of repeatedly calling the getter, or, if staying with the original, at least call the getter only once and store the result in a local variable. With what I assume is probably InProc session storage it won't make much of a difference, but in any other storage mode you'd repeatedly deserialize theComment
object for no reason.您需要使用
Page.LoadControl()
方法,请查看 这里顺便说一句:问题在于用这种方式以编程方式添加控件。
You need to use the
Page.LoadControl()
method instead , please look hereBTW:the problem is in adding the control programatically with that way.
使用:
并在某个地方发布带有内部异常的完整异常堆栈跟踪
Use:
and post somewhere full exception stack trace with inner exception(s)