Adding WebParts via code behind?

Discussion in 'ASP .Net' started by Bart Van Hemelen, Sep 4, 2006.

  1. I'm working on a project where the user of a site will receive custom
    content, depending on a set of parameters. The content will all be
    contained in UserControls (.ascx), that will be used as webparts on a
    page.

    We need to add the webparts dynamically to the site, depending on the
    status of the user: this involves a personalisation of a travel
    website, so a user can be "before" a trip, "during" a trip and "after"
    a trip, and depending on that status he'll see different content. (This
    is just one of the parameters, actually.) Of course, this all needs to
    integrate with the built-in personalisation offered by Profiles.

    However, all my experiments with adding UCs/WebParts via code behind
    have failed miserably: adding the works, but whenever the user clicks
    on a button inside a webpart, the postback causes the webparts to
    multiply.

    I've looked around, but so far I haven't yet found a working example of
    what I want to do. Can anyone help me out? Or am I trying to do
    something that is impossible?

    Tools & technologies: ASP.NET 2.0 / C# / Visual Studio 2005

    --
    BVH
     
    Bart Van Hemelen, Sep 4, 2006
    #1
    1. Advertising

  2. The WebPart Framework is designed to declaratively do the work for you,
    storing user choices in profile. When you dynamically add bits, you can end
    up with dupes in one of two ways.

    1. The user has an item in his profile and you have also added that item
    or
    2. The web part/control is held in ViewState and you dynamically add one,
    thinking this is the only way to change a control's state.

    In either case, you now have two objects (one created originally either by
    the user's choice or your initial load on the page (and into ViewState) plus
    the one you added when the form posted back).

    User Controls can act a lot like web parts, although they have fewer moving
    parts.

    Another thing: Page_Load is for loading a page. While this sounds like
    "well, duh" I find so few people really get the lifecycle. If you are
    loading a page and then allowing the controls to reside in ViewState, you
    need to make sure the initial load is ONLY in Not is Postback. In most
    cases, the pattern for page load is this (pseudocode):

    Page_Load

    If this is not a postback
    'Load elements necessary for page view
    Else
    'Only load things necessary for EVERY
    ' postback here (i.e. 100% of the time)
    End

    END

    You handle all other manipulation in the events. If you have a Page_Load
    that has a huge amount of code, you are probably working out a huge
    anti-pattern. That is not wise.
    What I would suggest is taking a step back and running through a full debug
    cycle on a page that is "failing" (by your spec -- i.e. adding additional
    web parts, etc.). Set watches on the number of controls, breakpoints in
    different methods, etc. and watch what is happening. Turn on and off
    ViewState. This exercise will not directly solve your issue, but it will
    truly enlighten you as to what Microsoft is doing for you.

    --
    Gregory A. Beamer
    MVP; MCP: +I, SE, SD, DBA

    *************************************************
    Think outside the box!
    *************************************************
    "Bart Van Hemelen" <> wrote in message
    news:...
    >
    > I'm working on a project where the user of a site will receive custom
    > content, depending on a set of parameters. The content will all be
    > contained in UserControls (.ascx), that will be used as webparts on a
    > page.
    >
    > We need to add the webparts dynamically to the site, depending on the
    > status of the user: this involves a personalisation of a travel
    > website, so a user can be "before" a trip, "during" a trip and "after"
    > a trip, and depending on that status he'll see different content. (This
    > is just one of the parameters, actually.) Of course, this all needs to
    > integrate with the built-in personalisation offered by Profiles.
    >
    > However, all my experiments with adding UCs/WebParts via code behind
    > have failed miserably: adding the works, but whenever the user clicks
    > on a button inside a webpart, the postback causes the webparts to
    > multiply.
    >
    > I've looked around, but so far I haven't yet found a working example of
    > what I want to do. Can anyone help me out? Or am I trying to do
    > something that is impossible?
    >
    > Tools & technologies: ASP.NET 2.0 / C# / Visual Studio 2005
    >
    > --
    > BVH
    >
     
    Cowboy \(Gregory A. Beamer\), Sep 4, 2006
    #2
    1. Advertising

  3. Cowboy (Gregory A. Beamer) wrote:
    > The WebPart Framework is designed to declaratively do the work for you,
    > storing user choices in profile. When you dynamically add bits, you can end
    > up with dupes in one of two ways.
    >
    > 1. The user has an item in his profile and you have also added that item
    > or
    > 2. The web part/control is held in ViewState and you dynamically add one,
    > thinking this is the only way to change a control's state.


    I now do this in Page_Load:

    if ( WebPartZone1.WebParts.Count)
    {
    // add UCs as WebParts here
    }

    which seems to have solved the problem: no duplicate webparts,
    postbacks work as they should etc. The state of those webparts -- i.e.
    if they are minimized or not -- also seems to get saved in the Profile.

    (Of course, it also means that I cannot put any WebParts on the page
    unless I do it via this method, but that's a price I'm willing to pay.)

    > You handle all other manipulation in the events. If you have a Page_Load
    > that has a huge amount of code, you are probably working out a huge
    > anti-pattern. That is not wise.


    I realise that, but other factors are more important to my employers:
    timely delivery, for at least a cost as possible. I'm particularly
    interested in knowing how I "should" solve this problem, i.e. how
    Microsoft wants me to solve this problem, since I do want to do this
    the proper way.

    However, after having gone through numerous examples I still haven't
    encountered any that resemble what I need to do, which is serve users
    with a custom list of webparts that depends on a number of factors
    which will be derived from an existing framework.

    --
    BVH
     
    Bart Van Hemelen, Sep 5, 2006
    #3
  4. Bart Van Hemelen wrote:
    > Cowboy (Gregory A. Beamer) wrote:
    > > The WebPart Framework is designed to declaratively do the work for you,
    > > storing user choices in profile. When you dynamically add bits, you can end
    > > up with dupes in one of two ways.
    > >
    > > 1. The user has an item in his profile and you have also added that item
    > > or
    > > 2. The web part/control is held in ViewState and you dynamically add one,
    > > thinking this is the only way to change a control's state.

    >
    > I now do this in Page_Load:
    >
    > if ( WebPartZone1.WebParts.Count)
    > {
    > // add UCs as WebParts here
    > }
    >
    > which seems to have solved the problem: no duplicate webparts,
    > postbacks work as they should etc. The state of those webparts -- i.e.
    > if they are minimized or not -- also seems to get saved in the Profile.


    It seems I spoke too soon. I just wrote some quick code to check if
    this would work, and after cleaning it up -- i.e. inserting the proper
    titles for each fo the uc-webparts for instance -- and retesting it, of
    course I got the webparts I expected, plus all the old ones that were
    saved in the profile.

    Considering that the website is going to be very dynamic in the future,
    we must have 100% control of the uc-webparts the user will have access
    to.

    So I need to either a) find the proper way of adding uc-webparts
    dynamically, or b) figure out a way to remove the improper ones from
    the profile.

    --
    BVH
     
    Bart Van Hemelen, Sep 5, 2006
    #4
  5. Bart Van Hemelen

    Serious Black

    Joined:
    Jan 18, 2010
    Messages:
    3
    Finally figured it out

    This has been hassling me for THREE FREAKIN MONTHS and I finally figured it out. There were seemingly-random duplicates of the web parts I was dynamically adding to an ASP.NET web page using the WebPartManager.AddWebPart( ... ) method. Kept accumulating more and more webparts over time, across sessions - AAARRGGHHHH. Set a breakpoint on the line of code that had the AddWebPart; it only stopped at that breakpoint ONCE golldarnit.... Varied by dev db server, user... Note this is plain vanilla ASP.NET web app, NOT inside SharePoint.

    Finally figured out it had something to do with the web part personalization provider and although I am not sure why it was remembering web parts when it chose to and if there is a cleaner approach than this, I have wasted too much time on this already and have to forge forward with all the work I am already behind on...

    You have to execute the following line of code:

    [YourWebPartManagerObject].Personalization.ResetPersonalizationState();

    at some point to "clean out" the web parts that the personalization provider has decided to squirrel away for the user. Just don't do it in Page_Load method or you get an infinite loop (google it; usually done in response to a button click or some other event handler; I'm going to try something at session start if I can refer to the one page that I have in my app that displays web parts, and get a reference to its WebPartManager - we'll see about that).

    Plus as a catch-all semi-hack, in my web page that displays web parts, before starting to add the web parts that SHOULD be there, I execute the following code:

    // Make absolutely sure there are no web parts "hanging around" due to personalization.
    foreach (WebPart webPartItem in _wpmMain.WebParts)
    {
    _wpmMain.DeleteWebPart(webPartItem);
    }


    Note that this is only necessary because we are doing very simplistic web part stuff in this one asp.net web page. i.e., adding web parts dynamically, but they are "read only", no manipulation by the user of the web parts etc. Now, the personalization provider needs to be enabled even just for that basic usage of web parts to work, but that makes it so that the "mysterious duplicating web parts" crap can happen.

    Hope this helps some other frustrated ASP.NET developers. :y:
     
    Serious Black, Jan 18, 2010
    #5
  6. Bart Van Hemelen

    Serious Black

    Joined:
    Jan 18, 2010
    Messages:
    3
    Refinement for previous post

    Otay, K.I.S.S. whenever possible, here's what I ended up doing to take care of the fact that the WebPartManager.Personalization.ResetPersonalizationState() does an automatic server.transfer back to the page that it is in (resulting in an infinite loop if you do it within the Page_Load). Just do the following at the top of the Page_Load of the page that you are doing the WebPartManager.AddWebPart() in:

    protected void Page_Load(object sender, EventArgs e)
    {
    if (!(Page.IsPostBack))
    {
    // Cleanup of web parts "hanging around" due to personalization.
    if (_wpmMain.WebParts.Count > 0)
    {
    _wpmMain.Personalization.ResetPersonalizationState();
    }

    .
    .
    .
    }

    Note that _wpmMain is the id of the WebPartManager in the aspx markup.

    And that is all the code that is necessary to take care of this specific situation.
     
    Serious Black, Jan 19, 2010
    #6
  7. Bart Van Hemelen

    Serious Black

    Joined:
    Jan 18, 2010
    Messages:
    3
    Sorry about formatting

    Sorry about the lack of indenting in the code, I put appropriate indentation in by hitting the space bar but they were taken out when posted.
     
    Serious Black, Jan 19, 2010
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Miller [msft]

    Re: Code Behind vs. no code behind: error

    Ben Miller [msft], Jun 27, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    620
    Alphonse Giambrone
    Jun 28, 2003
  2. Paal Berggreen

    Programmatic adding of WebParts

    Paal Berggreen, Jun 1, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    1,309
    Paal Berggreen
    Jun 1, 2005
  3. John

    Non-code behind to code behind

    John, Feb 19, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    509
    =?Utf-8?B?UGV0ZXIgQnJvbWJlcmcgW0MjIE1WUF0=?=
    Feb 19, 2007
  4. Ryan
    Replies:
    0
    Views:
    434
  5. ton
    Replies:
    0
    Views:
    281
Loading...

Share This Page