Issue with LLBLGenProDataSource

Posts   
 
    
rihadd
User
Posts: 22
Joined: 19-Sep-2007
# Posted on: 19-Sep-2007 17:12:26   

Hi,

LLBL Pro version = 2.5 final runtime version = v2.0.50727 Using ASP.NET 2.0 Database = MS SQL 2005

Scenario:

I have a Master page which contains a ContentPlaceHolder control to load web user contorls I've created. The user controls are being loaded dynamically at runtime. I have created a control that consists of a GridView that is bound to the LLBLGenProDataSource. I get the following exception thrown when attempting to switch from the user control that contains the LLBLGenProDataSource to another user control. Please note that this exception only ocurres when the LLBLGenProDataSource is present.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[NullReferenceException: Object reference not set to an instance of an object.] SD.LLBLGen.Pro.ORMSupportClasses.LLBLGenProDataSourceBase.OnPageLoadComplete(Object sender, EventArgs e) +59 System.EventHandler.Invoke(Object sender, EventArgs e) +0 System.Web.UI.Page.OnLoadComplete(EventArgs e) +2058120 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1209


Version Information: Microsoft .NET Framework Version:2.0.50727.832; ASP.NET Version:2.0.50727.832

The code in the Master page being used to load the controls dynamically:

protected void Menu1_MenuItemClick(object sender, MenuEventArgs e) {

    string loadPath = "~/UserControls/" + e.Item.Value + ".ascx";
    userControlPlaceHolder.Controls.Clear();
    Control control = LoadControl(loadPath);

    ((IPlugin)control).Host = new PluginManager();

    userControlPlaceHolder.Controls.Add(control);

    Session["LoadPath"] = loadPath;

}
Walaa avatar
Walaa
Support Team
Posts: 14951
Joined: 21-Aug-2005
# Posted on: 19-Sep-2007 17:54:08   

Would you please attach a repro project?

rihadd
User
Posts: 22
Joined: 19-Sep-2007
# Posted on: 19-Sep-2007 18:41:26   

Attached is repro project.

rihadd
User
Posts: 22
Joined: 19-Sep-2007
# Posted on: 19-Sep-2007 18:43:55   

here...

Walaa avatar
Walaa
Support Team
Posts: 14951
Joined: 21-Aug-2005
# Posted on: 20-Sep-2007 17:03:33   

in the Page_Load handler, don't add controls to the place holder, as follows:

            if (Session["LoadPath"] != null)
            {

                Control control = LoadControl(Session["LoadPath"].ToString());
                

                userControlPlaceHolder.Controls.Clear();
                //userControlPlaceHolder.Controls.Add(control); // not needed
            }

Just comment that line and everything will work just fine.

jtoast
User
Posts: 12
Joined: 05-Nov-2007
# Posted on: 06-Jan-2008 21:26:29   

I am having the same issue. From the error message, I am guessing that the LLBLGenProDataSourceBase registers itself with the page LoadComplete event. However if a control containing an LlblGenProDataSource is dynamically removed before the completion of the page lifecycle, then the error described in the first post seems to occur.

Is there a way to unregister the LLBLGenProDataSourceBase from the Page.LoadComplete event? Alternatively, is there another way to avoid this error?

The current flow of the my code is as follows:

Page OnInit event: - dynamically load control containing LLBLGenDataSource into placeholder*

Button Onclick event - Retrieve and persist data from the loaded control - Clear the placeholder, and dynamically load a different control (varies based on user input)

*The original control must be loaded in the OnInit event, so that the viewstate loads correctly.

Thanks for any help

Walaa avatar
Walaa
Support Team
Posts: 14951
Joined: 21-Aug-2005
# Posted on: 07-Jan-2008 10:09:12   

Would you please attach a repro project?

Also please provide more info as described here: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7717 Next time please create a new thread as stated in the above link.

jtoast
User
Posts: 12
Joined: 05-Nov-2007
# Posted on: 08-Jan-2008 04:29:39   

Hi Walaa

Thanks for your response. Please find repo project attached. Just open solution, hit F5 and you should be good to go. You can see the issue by doing the following:

  • Hit button 1 (note that user control loads)
  • Hit button 3 (note that user control stays, even across postback)
  • Hit button 2 -> Error!

This error only occurs when the user control contains an LLBLGenProDataSource

Thanks for any help

Walaa avatar
Walaa
Support Team
Posts: 14951
Joined: 21-Aug-2005
# Posted on: 08-Jan-2008 13:31:06   

The following should work:

    public partial class WebForm1 : System.Web.UI.Page
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (Session["LoadPath"] != null)
            {
                Control control = LoadControl(Session["LoadPath"].ToString());

                uxPlaceHolder.Controls.Clear();
                uxPlaceHolder.Controls.Add(control);
            }
        }
        
        protected void uxBtn1_Click(object sender, EventArgs e)
        {
            string loadPath = "~/UserControls/WebUserControl1.ascx";
            Session["LoadPath"] = loadPath;
        }

        protected void uxBtn2_Click(object sender, EventArgs e)
        {
            string loadPath = "~/UserControls/WebUserControl2.ascx";
            Session["LoadPath"] = loadPath;
        }

        protected void uxBtn3_Click(object sender, EventArgs e)
        {
            uxLbl.Text = "Something else done";
        }

        protected void Page_PreRender(object sender, EventArgs e)
        {
                    if (Session["LoadPath"] != null)
                    {
                        Control control = LoadControl(Session["LoadPath"].ToString());
                        uxPlaceHolder.Controls.Clear();
                        uxPlaceHolder.Controls.Add(control);
                    }
        }
    }
jtoast
User
Posts: 12
Joined: 05-Nov-2007
# Posted on: 08-Jan-2008 16:25:58   

Hi Walaa

That looks like a useful work-around. However, It is plausible that in some circumstances it may be necessary to unload a control prior to PreRender, in which case the issue would still arise.

Ideally there would/should be a way to unload the control more gracefully, which would probably need to include unregistering the event that is registered with page.loadcomplete. If this is not currently possible then it would probably be a good feature to add. I would be interested in your thoughts on this. I could start an new post in the feature requests section of you thought this was appropriate.

Thanks again for your input

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39620
Joined: 17-Aug-2003
# Posted on: 08-Jan-2008 16:40:19   

The control currently doesn't override OnUnload(), which is a method which could help, but I doubt it. Looking at the ObjectDataSource, it also binds to the event in OnInit (similar to our datasource), however it doesn't implement code to unbind from that event.

So in short: I don't think there's a way to unregister the control right before the prerender, or at least not really foreseen by MS. The thing is: the datasourcecontrols are used / materialized/ bound in various stages in the page life cycle, so using them in 1 stage and then removing them from another isn't really helpful. If you want to get rid of the controls, simply get rid of them before anything else. (it might come as a surprise, but I truly hate it how MS has setup ASP.NET's page lifecycle... it's so incredibly unclear when what happens.. anyway wink )

What we could do is add some code to help avoiding the error. However that's also not ideal, as the event IS bound...

Frans Bouma | Lead developer LLBLGen Pro
jtoast
User
Posts: 12
Joined: 05-Nov-2007
# Posted on: 08-Jan-2008 17:39:48   

Hi Frans

Thanks for your reply.

Could you simply expose the OnPageLoadComplete method of the LLBLGenProDataSource as public, so that the following would then be possible:

Page.LoadComplete -= new EventHandler( LLBLDataSourceInstance.OnPageLoadComplete );

This should then solve the problem I think. You could even wrap that in a method instead (e.g. public void UnregisterEvents())

Does that make sense, or i have missed something crucial?!

Thanks

Walaa avatar
Walaa
Support Team
Posts: 14951
Joined: 21-Aug-2005
# Posted on: 09-Jan-2008 10:52:25   

Could you simply expose the OnPageLoadComplete method of the LLBLGenProDataSource as public, so that the following would then be possible:

Page.LoadComplete -= new EventHandler( LLBLDataSourceInstance.OnPageLoadComplete );

If the event is exposed then you I guess you should unregister it as follows:

Page.LoadComplete -=  LLBLDataSourceInstance.OnPageLoadComplete;

without using new to instantiate it.

Anyway until Frans reply to you and whether this is going to be built in or exposed to public, would you please use the Source Code of the runtime library, modify it and build your own version and see if any of your suggestions will work flawlessly.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39620
Joined: 17-Aug-2003
# Posted on: 09-Jan-2008 11:15:15   

I don't like such a method being public. It encourages hacky behavior, because WHEN to call that method? Do you have to call it always, or just when you 'need' it but when is that?

So people will call it regardless of when they need it or not. What's odd is that ObjectDataSource for example doesn't unsubscribe from this event.

So I think it's better to add code which doesn't make the event handler crash. I've added that code to the event handler, could you check the attached dll ? (It's build 2.5 01092008 )

Frans Bouma | Lead developer LLBLGen Pro
jtoast
User
Posts: 12
Joined: 05-Nov-2007
# Posted on: 09-Jan-2008 16:07:17   

Bingo - that has solved the problem. Will that make the next release?

Thanks for your help

Walaa avatar
Walaa
Support Team
Posts: 14951
Joined: 21-Aug-2005
# Posted on: 09-Jan-2008 16:20:20   

I believe it will.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39620
Joined: 17-Aug-2003
# Posted on: 09-Jan-2008 20:44:39   

It already has simple_smile (the dll attached to that post is the last build, so you can continue using it simple_smile )

Frans Bouma | Lead developer LLBLGen Pro