My career in technology

This is part nine of my exploration of a solution I recently completed, using an event handler to programmatically create and configure a site based on form data provided by users and a site template created and managed by a SharePoint power user.

Now we get to the mystery. And you get to watch my head explode….

(Links to the other parts in the series are at the bottom of the post!)

I had completed editing some web parts on a web part page:

        private void DoFixWebParts()
        {
            //DoRemovePCPage();
            DoUpdateProjectProcessWebPart();
            DoFilterAudienceOnTaskWebPart();
            DoSetProjectDatabaseDisplayWebPart();
            DoFixProjKickoffContentEditorWebPart();

            //update BuildWeb
            BuildWeb.Update();
        }

If you remember, there were 12 web parts on the landing page, Welcome.aspx:

  • 2 Content Editor web parts
  • 2 Data View web parts
  • 6 List View web parts
  • 1 User Tasks web part
  • 1 Key Performance Indicator web part

It is that last one that became a real pain. The KPI web part is a Microsoft.SharePoint.Portal.WebControls.KPIListWebPart. This is what it is supposed to look like, and does before any edits are made to the web part page:

But here is what it looks like after I edit the web part page:

The KPI web part has lost its configuration. It lost its title and its reference to the KPI list. But what caused it to blow up?

Initially I removed DoFilterAudienceOnTaskWebPart(); (it was the first of the web part page tasks I completed during development) and that seemed to solve the problem, so I went down the rabbit hole looking for causes. It turns out, though, that any editing on the web part page caused the KPI web part to lose its configuration.

When I remove the some of the code…

        private void DoUpdateProposalProcessWebPart()
        {
            SPList ListToGetInfoFrom = BuildWeb.Lists["Pages"];
            SPListItem ListItemToGetInfoFrom = ListToGetInfoFrom.GetItemById(41);
            SPFile WebpartPageToUpdate = BuildWeb.GetFile(ListItemToGetInfoFrom.Url);
            try
            {
                WebpartPageToUpdate.CheckOut();

                //CODE COMMENTED OUT HERE

                WebpartPageToUpdate.CheckIn("Initial Site Setup - ProposalProcessWebPart");
                WebpartPageToUpdate.Publish("Initial Site Setup - ProposalProcessWebPart");
            }
            catch (Exception ex)
            {
                //error hendling code goes here, NOT commented out
            }
        }

…the KPI part does not lose its configuration. But add back just the using statement…

        private void DoUpdateProposalProcessWebPart()
        {
            SPList ListToGetInfoFrom = BuildWeb.Lists["Pages"];
            SPListItem ListItemToGetInfoFrom = ListToGetInfoFrom.GetItemById(41);
            SPFile WebpartPageToUpdate = BuildWeb.GetFile(ListItemToGetInfoFrom.Url);
            try
            {
                WebpartPageToUpdate.CheckOut();
                using (SPLimitedWebPartManager MyWPM = WebpartPageToUpdate.GetLimitedWebPartManager(PersonalizationScope.Shared))
                {
                    //CODE COMMENTED OUT HERE
                }
                WebpartPageToUpdate.CheckIn("Initial Site Setup - ProposalProcessWebPart");
                WebpartPageToUpdate.Publish("Initial Site Setup - ProposalProcessWebPart");
            }
            catch (Exception ex)
            {
                //error hendling code goes here
            }
        }

…and the KPI web part loses its configuration.

Since running up against this problem, I’ve sought the advice of many very smart people. Some have suggested that the using statement is not needed (although others have said that it is). So I tried running both of the following ways:

                SPLimitedWebPartManager MyWPM = BuildWeb.GetLimitedWebPartManager(ListItemToGetInfoFrom.Url, PersonalizationScope.Shared);
                WebpartPageToUpdate.CheckOut();
                SPLimitedWebPartManager MyWPM = WebpartPageToUpdate.GetLimitedWebPartManager(PersonalizationScope.Shared);
                WebpartPageToUpdate.CheckOut();

Removing the using statement still did not resolve the issue. As soon as the SPLimitedWebPartManager is called, the KPI web part drops its configuration.

I tried creating a separate step to reconfigure the web part. After running all the other procedures in the event handler, I set the last step to be DoFixKPIWebpart(). I set breakpoints to show me the status of the web part during the reconfiguration. At the beginning of the process the web part shows as unconfigured. I set the title, and the web part responds with the title. The code finishes the procedure and exits back to the point that called it…

        private void DoFixKPIWebpart()
        {
            Microsoft.SharePoint.Portal.WebControls.KPIListWebPart wp;
            try
            {
                this.DisableEventFiring();
                SPList ListToGetInfoFrom = BuildWeb.Lists["Pages"];
                SPListItem ListItemToGetInfoFrom = ListToGetInfoFrom.GetItemById(41);
                SPFile WebpartPageToUpdate = BuildWeb.GetFile(ListItemToGetInfoFrom.Url);
                WebpartPageToUpdate.CheckOut();

                SPLimitedWebPartManager MyWPM = WebpartPageToUpdate.GetLimitedWebPartManager(PersonalizationScope.Shared);

//                using (SPLimitedWebPartManager MyWPM = WebpartPageToUpdate.GetLimitedWebPartManager(PersonalizationScope.Shared))    // "/Pages/Welcome.aspx"
//                {
                    string WebPartTitle;
                    wp = (KPIListWebPart)MyWPM.WebParts[10];
                    WebPartTitle = wp.Title;
                    if (WebPartTitle == "" | WebPartTitle == null)
                    {
                        wp.Title = "Key Performance Indicators";
                        wp.ListURL = parentSiteUrl + siteName + "/Lists/Proposal KPIs/KPIListViewPage.aspx";
                        wp.TitleUrl = parentSiteUrl + siteName + "/Lists/Proposal KPIs/KPIListViewPage.aspx";
                        //Call SaveChanges method 
                        MyWPM.SaveChanges(wp);
                    }
//                }
                WebpartPageToUpdate.CheckIn("Initial Site Setup - Fix KPI Web Part");
                WebpartPageToUpdate.Publish("Initial Site Setup - Fix KPI Web Part");
                //update BuildWeb
                BuildWeb.Update();
            }
            catch
            {
                WriteToLog("DoFixKPIWebpart", "Error");
            }
            finally
            {
                this.EnableEventFiring();
            }
        }

…and it doesn’t stick. The web part has lost its configuration again! (Again, this is true both with and without the using statement, as shown – but commented out – in the code above.)

Blam! (I told you that you would get to see my head explode…)

I don’t know what to tell you. If anyone else is having the same problem, or especially if you have had the same problem and solved it (!!!) please comment below.

In the meantime, the end user had a workaround. Once the new site is created, the user:

  1. goes to the newly created site
  2. clicks “Open the tool pane” on the deconfigured web part
  3. adds the title in the title field
  4. clicks on the browse icon for the indicator list
  5. clicks on the site name on the left side
  6. clicks on the KPI list
  7. clicks OK to close the browse dialog
  8. clicks OK in the tool pane

Yes it is a few steps, but it is many, many fewer than the user used to have to go through, and fewer than the steps to configure the things that deconfigure the KPI web part.

I would love to hear alternatives, though.

Coming up, in Part Eleven, I wrap up the site creation steps:

                //ToDo #8:  Add items to subsite lists reflecting this Request
                DoCreateItemInSubsiteLists();
                //ADD WEB SITE ADDRESS TO THE FORM
                DoUpdateFormWithWebsiteAddress();

But first, I decided to move up the post on logging next because of recent events (in the log, no less). Part Ten, the Log Blog!

(We’re getting close to the end of the series, folks!)

I’d love your feedback. Is there something you think I could be doing better? Are there questions about the code I haven’t answered? Am I full of it? Let me know! Feel free to use these code samples in accordance with my usage policy.

Check out Part One here (The Setup).
Check out Part Two here (The Decision).
Check out Part Three here (If You Built It…).
Check out Part Four here (…They Will Come).
Check out Part Five here (Bring ‘Em All In).
Check out Part Six here (Ride the CAML!).
Check out Part Seven here (Pointing The Way)
Check out Part Eight here (Taking Part!).
You are reading Part Nine.
Part Ten (The Log Blog) is coming!

More posts about SharePoint.

Advertisements

Comments on: "Automated SharePoint Site Provisioning Solution – Act Nine (Deconfigured)" (6)

  1. I just got a requirement from my client for site provisioning and I’m using share point server 2010. Is this solution applicable for my scenario? or it works only for MOSS 2007? Please let me know.

    • In total it is a 2007 solution, but parts can be applicable to 2010. For instance, 2010 does not support .stp files (the site template used to generate the sites in this scenario). I’m pretty sure that much of the other code for modifying the site, libraries, lists, and webparts are going to be pretty much the same (though of course for this solution I am not modifying any of the properties that are new to 2010, like tags and such).

      I’m ramping up to migrate to 2010 (one big reason why I haven’t had time to wrap up the series), and of course, modifying this solution is going to be a big priority once the main migration is completed.

      I’ll be sure to provide modified code once I get that far!

    • Based on some preliminary reading, the primary change for going to 2010 is going to be changing the .stp file to a .wsp file.

      In our current environment, the .stp has been created using an empty site. When updates need to be made to the template, the updates are applied to the site and saved as a new .stp file. In 2010, the .stp files are no longer used, so we will need to re-create the template from the original site as a wsp file and use that to create the new sites.

  2. Hello Jim,

    Wondering if you’ve updated the project for use with SP 2010…? Also do you have the complete project…? Thanks so much for your work!!! This is pretty exciting functionality..!

    • I did not update the project for SP2010. I left the company shortly after we implemented SP2010 and started migrating the data. To my knowledge, the company is still in the process of migrating the data, and the team lead for whom this was implemented is no longer there as well, so there may not ever be an update for it.

      And of course, along with that, as I’m no longer with that company, I don’t have the complete project. Plus, there were some specific-to-the-organization elements that I genericized for the blog posts. (Otherwise they wouldn’t have let me publish!)

      You would probably be better off anyway copying the code form the posts and doing a little fixup, especially as you may not need all of the modules I had to implement to meet the requirements.

      Good luck, and if you have questions, feel free to post them here in the comments!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: