CSDN-CSDN社区-.NET技术-ASP.NET

收藏 PostBack后page对象和自定义web control对象为null值[问题点数:50,无满意答案结帖,结帖人:yww_poison]

楼主发表于:2008-01-10 15:25:24
在ajax的update panel里放入了一个ascx文件。但是postback以后由于题目的问题。报错。
这种情况有人碰到过吗?
怎么办?
回复次数:18
#1楼 得分:0回复于:2008-01-10 15:40:08
但是postback以后由于题目的问题。报错。
**********************************
??
#2楼 得分:0回复于:2008-01-10 17:38:52
我的意思是postback以后报错对象为定义,用debug跟踪进去发现this对象是一个XXX_XXX.aspx但是居然没有Page属性。
而且自定义的web control 也为null 值。为什么啊。
#3楼 得分:0回复于:2008-01-11 15:42:34
每人能回答吗?我想把代码贴上来的,可是东西不少。我决定只粘贴页面和和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();
            }

        }

还有一部分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
            }


#4楼 得分:0回复于:2008-01-11 15:49:05
AddObjectPopup.Windows.Add(new  PopupWindow("loading",  "Company"));
                                AddObjectPopup.Windows.Add(new  PopupWindow("loading",  "SubCompany"));
                                AddObjectPopup.Windows.Add(new  PopupWindow("loading",  "CallType"));
这些代码放到if  (Page.IsPostBack  ==  false  )
                        { }之外,就是说不用if(!IsPostBack),
只要不是在页面上摆好的控件,创建都不能放到if(!IsPostBack){}中创建否则出错,找不到那些控件。
#5楼 得分:0回复于:2008-01-11 16:05:09
我理解你的意思,不过这个AddObjectPopup控件是放在UpdatePanel之外的。而且和我的自定义控件没有关系。只是用来生成一堆popup的窗口的javascript object,给客户端的javascript调用的,所以只需要在页面生成时注入一次。

我的自定义控件SimpleOjbect是在页面上摆好来生成的。
<%@ 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>
......
#6楼 得分:0回复于:2008-01-11 16:13:11
如果不那样做,你就不要通过AddObjectPopup来取PopupWindow的值了,你可以考虑使用Request.Form("")或者把你需要的值通过js放到一个隐藏控件中,
#7楼 得分:0回复于:2008-01-11 16:23:26
你好像理解错了。
AddObjectPopup是DevExpress组件里的一个popupControl,我注册了几个popupwindow对象给客户端的javascript调用而已。
Windows.Add方法是控件固有的,并不是我写的用来取值的函数。
#8楼 得分:0回复于:2008-01-11 16:30:15
即使我把AddObjectPopup.Windows.add这几行代码放到了!IsPostBack外,问题仍然存在。虽然我很肯定这一点,刚才还是改动了并测试了一次,和我想的一样。
#9楼 得分:0回复于:2008-01-11 16:31:10
把object对象存好!
#10楼 得分:0回复于:2008-01-11 16:42:20
大哥,你这句话太天马行空了吧。啥object对象啊。。。
  • jetxia用户头像
  • jetxia
  • (笑缘)
  • 等 级:
#11楼 得分:0回复于:2008-01-11 16:48:10
大体看了一下你的代码, 没有发现什么可疑的。
再仔细 找找。
#12楼 得分:0回复于:2008-01-11 17:36:13
我最想不通的是我在page_load或者page_init中设下断点,居然发现this.Page未定义。
this对象有各个成员,看上去也是一个页面aspx对象,而该对象继承自System.Web.UI.Page,但是里面居然少了Page属性。为什么呢?
明天我再仔细用debug看看,然后贴图?
#13楼 得分:0回复于:2008-01-15 10:40:37
奇怪的是现在page对象都显示为有直的。但自定义的控件仍然是空的。
通过aspx摆上去的控件为什么是空值呢?考虑到如果我点击客户端的时候慢一点(相应的是ListBox的OnSelectedIndexChanged事件)就不会有这个错误。会不会是客户端的ListBox还没有完全生成好我就点了,所以出现这种问题?如果是,又应该如何避免呢?
#14楼 得分:0回复于:2008-01-15 10:44:48
如果是DataGrid中的列,你把它转成模板列就行了。
#15楼 得分:0回复于:2008-01-15 10:54:59
没有用到grid啊。是我自己做的web control里有一个autopostback的listbox,而web control是放在update panel里的。没有复杂的控件。
#16楼 得分:0回复于:2008-01-15 16:21:51
唉,还是我自己瞎打瞎撞解决了。
我把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里面就完了.
#17楼 得分:0回复于:2008-01-15 16:33:46
你如果移动到原来的地方也是可以的
关键是把你的object存好!
-_-
#18楼 得分:0回复于:2008-01-16 12:45:52
lz1201048 兄,我还是没有看懂你说的把对象存好的意思。存在哪里?
相关问题
动态增加HtmlTable的Row时,Postback后消失了,怎么办? .NET技术/ ASP ...
【精华】如何让ascx里2个DroDdownList联动起来?100分+ .NET技术/ ASP ...
超难,权限的控制IHttpModule,不够分再加.NET技术/ ASP.NET - CSDN社区 ...
(C#)动态生成控件成功,引用生成的控件失败(附程序) .NET技术/ ASP ...
ASP.NET .NET技术/ ASP.NET - CSDN社区community.csdn.net