我的意思是postback以后报错对象为定义,用debug跟踪进去发现this对象是一个XXX_XXX.aspx但是居然没有Page属性。 而且自定义的web control 也为null 值。为什么啊。
每人能回答吗?我想把代码贴上来的,可是东西不少。我决定只粘贴页面和和web control的page_load和page_init代码好了。问题可能出现在这两个地方。 前台的页面关系应该不大,所以就不贴代码了。 aspx的 c# code: public partial class ConfigCallType : System.Web.UI.Page { public Session session; protected void Page_Load(object sender, EventArgs e) { if (this.Page == null || this.Com == null) return; Object layer = Application["XpoLayer"]; session = new DevExpress.Xpo.Session(layer as IDataLayer); if (Page.IsPostBack == false ) { //for the first time AddObjectPopup.Windows.Add(new PopupWindow("loading", "Company")); AddObjectPopup.Windows.Add(new PopupWindow("loading", "SubCompany")); AddObjectPopup.Windows.Add(new PopupWindow("loading", "CallType")); } } protected void Page_Init(object sender, EventArgs e) {
if (this.Page == null || Com == null) { if (this.Page != null && Page.IsPostBack == true) { this.Response.Clear(); this.Response.End(); }//for the bug that I can't solve if (this.Page != null && Page.IsPostBack == false) { Response.Redirect(Request.Url.ToString()); } //for the bug of logging out }
Object layer = Application["XpoLayer"]; session = new DevExpress.Xpo.Session(layer as IDataLayer);
//set up relation SubCom.ParentObject = Com; ct.ParentObject = SubCom; Com.PageUser = User.Identity.Name; SubCom.PageUser = User.Identity.Name; Com.LimitedByUser = true; SubCom.LimitedByUser = true; // set up event Com.BubbleRaise += new EventHandler(Com_BubbleRaise); SubCom.BubbleRaise += new EventHandler(SubCom_BubbleRaise); ct.BubbleRaise += new EventHandler(ct_BubbleRaise); } WebControl的代码: SimpleObject.ascx.cs ,上述页面中定义的Com, SubCom和ct都是该控件的对象。 protected void Page_Load(object sender, EventArgs e) { if (session == null) { System.Type type = this.Page.GetType(); FieldInfo pi = type.GetField("session", BindingFlags.Public | BindingFlags.Instance); if (pi != null) { session = (Session)pi.GetValue(this.Page); } } if (this.Page.IsPostBack == false) { BindObject(); }
#endregion其它的BindObject方法之类的代码感觉和问题关系不大就不贴了。代码里使用了devExpress,但是用的是XPO这个ORM,感觉和这种页面生命周期的问题应该没什么大关系。问题再说一次,就是this.Page以及com,subCom等对象为null而报错。在page_init里出错的,一开始我是把page_init里的代码都放到page_load里的,但是也是同样地出错的。我就想不通了,凭什么AJAX updatepanel postback回来的时候this.Page都为null值?(在debug的watch里看到的)。 而且吧它也不是每次都为null,感觉如果每次点击前等一小会就没问题,像是等页面在上一次AJAX的东西完全处理完的感觉。 其中,下面的代码就是用来避免页面上出错的。用了Response.End(),就可以不报错,但是对事件的AJAX响应就没有了,客户端没有更新。所以只能是一个临时的workaround. if (this.Page == null || Com == null) { if (this.Page != null && Page.IsPostBack == true) { this.Response.Clear(); this.Response.End(); }//for the bug that I can't solve if (this.Page != null && Page.IsPostBack == false) { Response.Redirect(Request.Url.ToString()); } //for the bug of logging out }
**********************************
??
而且自定义的web control 也为null 值。为什么啊。
前台的页面关系应该不大,所以就不贴代码了。
aspx的 c# code: public partial class ConfigCallType : System.Web.UI.Page
{ public Session session; protected void Page_Load(object sender, EventArgs e)
{ if (this.Page == null || this.Com == null) return; Object layer = Application["XpoLayer"];
session = new DevExpress.Xpo.Session(layer as IDataLayer);
if (Page.IsPostBack == false )
{
//for the first time
AddObjectPopup.Windows.Add(new PopupWindow("loading", "Company"));
AddObjectPopup.Windows.Add(new PopupWindow("loading", "SubCompany"));
AddObjectPopup.Windows.Add(new PopupWindow("loading", "CallType"));
}
} protected void Page_Init(object sender, EventArgs e)
{
if (this.Page == null || Com == null)
{
if (this.Page != null && Page.IsPostBack == true) { this.Response.Clear(); this.Response.End(); }//for the bug that I can't solve
if (this.Page != null && Page.IsPostBack == false) { Response.Redirect(Request.Url.ToString()); } //for the bug of logging out
}
Object layer = Application["XpoLayer"];
session = new DevExpress.Xpo.Session(layer as IDataLayer);
//set up relation
SubCom.ParentObject = Com;
ct.ParentObject = SubCom; Com.PageUser = User.Identity.Name;
SubCom.PageUser = User.Identity.Name;
Com.LimitedByUser = true;
SubCom.LimitedByUser = true;
// set up event
Com.BubbleRaise += new EventHandler(Com_BubbleRaise);
SubCom.BubbleRaise += new EventHandler(SubCom_BubbleRaise);
ct.BubbleRaise += new EventHandler(ct_BubbleRaise);
}
WebControl的代码:
SimpleObject.ascx.cs ,上述页面中定义的Com, SubCom和ct都是该控件的对象。
protected void Page_Load(object sender, EventArgs e)
{
if (session == null)
{
System.Type type = this.Page.GetType();
FieldInfo pi = type.GetField("session", BindingFlags.Public | BindingFlags.Instance);
if (pi != null)
{
session = (Session)pi.GetValue(this.Page);
}
}
if (this.Page.IsPostBack == false)
{
BindObject();
}
}还有一部分web control的自定义事件的代码也一起贴上来了: protected void RefreshBtn_Click(object sender, EventArgs e)
{
BindObject();
BubbleUp(sender, e);
} private void BubbleUp(object sender, EventArgs e)
{
EventHandler BubbleRaised = (EventHandler)Events[EventBubbleRaised];
if (BubbleRaised != null)
BubbleRaised(this, e);
} private static readonly object EventBubbleRaised = new object();
#region Event Handler
public event EventHandler BubbleRaise
{
add
{
Events.AddHandler(EventBubbleRaised, value);
}
remove
{
Events.RemoveHandler(EventBubbleRaised, value);
}
}
#endregion其它的BindObject方法之类的代码感觉和问题关系不大就不贴了。代码里使用了devExpress,但是用的是XPO这个ORM,感觉和这种页面生命周期的问题应该没什么大关系。问题再说一次,就是this.Page以及com,subCom等对象为null而报错。在page_init里出错的,一开始我是把page_init里的代码都放到page_load里的,但是也是同样地出错的。我就想不通了,凭什么AJAX updatepanel postback回来的时候this.Page都为null值?(在debug的watch里看到的)。
而且吧它也不是每次都为null,感觉如果每次点击前等一小会就没问题,像是等页面在上一次AJAX的东西完全处理完的感觉。
其中,下面的代码就是用来避免页面上出错的。用了Response.End(),就可以不报错,但是对事件的AJAX响应就没有了,客户端没有更新。所以只能是一个临时的workaround.
if (this.Page == null || Com == null)
{
if (this.Page != null && Page.IsPostBack == true) { this.Response.Clear(); this.Response.End(); }//for the bug that I can't solve
if (this.Page != null && Page.IsPostBack == false) { Response.Redirect(Request.Url.ToString()); } //for the bug of logging out
}
AddObjectPopup.Windows.Add(new PopupWindow("loading", "SubCompany"));
AddObjectPopup.Windows.Add(new PopupWindow("loading", "CallType"));
这些代码放到if (Page.IsPostBack == false )
{ }之外,就是说不用if(!IsPostBack),
只要不是在页面上摆好的控件,创建都不能放到if(!IsPostBack){}中创建否则出错,找不到那些控件。
<%@ Register Src="~/Controls/SimpleObject.ascx" TagName="SimpleObject" TagPrefix="SO" %>
......
<td>
<SO:SimpleObject runat="server" id="Com" Name="Company" ></SO:SimpleObject>
</td>
<td>=></td>
<td>
<SO:SimpleObject runat="server" id="SubCom" Name="SubCompany" ></SO:SimpleObject>
</td>
......
AddObjectPopup是DevExpress组件里的一个popupControl,我注册了几个popupwindow对象给客户端的javascript调用而已。
Windows.Add方法是控件固有的,并不是我写的用来取值的函数。
this对象有各个成员,看上去也是一个页面aspx对象,而该对象继承自System.Web.UI.Page,但是里面居然少了Page属性。为什么呢?
明天我再仔细用debug看看,然后贴图?
通过aspx摆上去的控件为什么是空值呢?考虑到如果我点击客户端的时候慢一点(相应的是ListBox的OnSelectedIndexChanged事件)就不会有这个错误。会不会是客户端的ListBox还没有完全生成好我就点了,所以出现这种问题?如果是,又应该如何避免呢?
我把update panel放到了ascx控件内,而不是放在aspx页面里面,一个字没加,一个字没减,只是移动了位置。
但是,我不想结贴,因为我没有找到问题的原因。我找到的一篇文章,也是说ajax方法和控件之间顺序,但它那是Accordion控件,和我的完全不一样。
http://forums.asp.net/t/1057411.aspx
但我注意到一句话:This is because AJAX Accordion is static method. It will get create before ReportViewer object, 也就是说有AJAX方法在postback之后用户object还没生成的可能?希望能有达人解释一下AJAX和服务端控件生成的时序问题和解决方法。
以及为什么我的例子中update panel的位置会造成问题?
aspx的代码很简单,update panel用的是默认属性,不能再少了:
原来的:
<asp:UpdatePanel runat="server" ID="up1">
<ContentTemplate>
<table border="0px">
<tr>
<td>
<SO:SimpleObject runat="server" id="Com" Name="Company" ></SO:SimpleObject>
</td>
<td>
<SO:SimpleObject runat="server" id="SubCom" Name="SubCompany" ></SO:SimpleObject>
问题解决后的代码就是把
<asp:UpdatePanel runat="server" ID="up1">
<ContentTemplate>
移到SimpleObject ascx里面就完了.
关键是把你的object存好!
-_-