Archive for the 'C#' Category

Programmatically removing all WebParts from a page in MOSS 2007

April 15, 2008

So I haven’t been around blogging for a while due to having a little downtime and finishing up a project I’ve been working on. I’ve just started a new project which involves migrating a very large SPS 2003 implementation to MOSS 2007.

Hopefully I’ll be back blogging regularly with some useful SharePoint related articles and to start off with I’m going to demonstrate how to delete all WebParts from a WebPart page programmatically.

This requirement came up recently as I needed to create a feature to delete all WebParts from the standard MySite template and add some custom WebParts when every MySite was provisioned.

The steps to accomplish this were as follows:

  1. Create a feature that when activated deleted all WebParts from the page and added my custom ones on.
  2. Create a feature stapler to staple my new feature to the SPSPERS template so the feature is activated each time a new MySite was provisioned.

I’m only going to cover step 1 here as there are plenty of great articles out there that explain feature stapling e.g. http://blogs.msdn.com/cjohnson/archive/2006/11/01/feature-stapling-in-wss-v3.aspx

Ok first we need to create a class that inherits from the SPFeatureReceiver class like so:

public class CustomMySiteWebPartsFeature : SPFeatureReceiver

The SPFeatureReceiver class is an abstract class with the following four abstract methods:

  • FeatureActivated(SPFeatureReceiverProperties properties)
  • FeatureDeactivating(SPFeatureReceiverProperties properties)
  • FeatureInstalled(SPFeatureReceiverProperties properties)
  • FeatureUninstalling(SPFeatureReceiverProperties properties)

We need to override all four of these methods but we only need to write our code in the FeatureActivated method so leave the others blank.

The first thing we do is get an instance of the SPWeb class which we can do by using the properties variable that is passed to the method.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{

using
(SPWeb web = properties.Feature.Parent as SPWeb)

{

}
}

Next we need to check that this is definately a MySite page we are working on just in case the feature gets activated on another site. We can do this by checking the WebTempate property of our SPWeb instance.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{

using
(SPWeb web = properties.Feature.Parent as SPWeb)

{

if
(web.WebTemplate == “SPSPERS” || web.WebTemplate == “SPSMSITEHOST”)

{

}
}
}

To actually manipulate WebParts on our page we need to get an instance of the SPLimitedWebPartManager
class like this:

SPLimitedWebPartManager manager = web.GetLimitedWebPartManager(“default.aspx”, PersonalizationScope.Shared);

And as you can see we call the GetLimitedWebPartManager method of our SPWeb instance for the page we want to manipulate.

Now we can begin to delete the WebParts. Below is the code I used to accomplish this.

List<Microsoft.SharePoint.WebPartPages.WebPart> webParts = new
List<Microsoft.SharePoint.WebPartPages.WebPart>();

foreach (Microsoft.SharePoint.WebPartPages.WebPart webPart in manager.WebParts)
{
webParts.Add(webPart);
}

foreach (Microsoft.SharePoint.WebPartPages.WebPart webPart in webParts)
{
manager.DeleteWebPart(webPart);
}

I first add all the WebParts to a collection then interate over that collection calling the DeleteWebPart method of our SPLimitedWebPartManager instance. We need to do this because calling DeleteWebPage while interating over the WebParts collection causes an exception as the collection has been altered during the enumeration.

When this is done we can use the AddWebPart method of the SPLimitedWebPartManager passing it an instance of the WebPart you want to add, the WebPartZone id you want to add the WebPart to and the index at which you want to add the WebPart within the zone.

After all this is done don’t forget to dispose the SPLimitedWebPartManager instance and call Update on the SPWeb instance:

manager.Dispose();
web.Update();

And that’s all there is to it.

Hope it was helpful.

Dynamically adding WebParts using WebPartManagerInternals class

January 10, 2008

I’m currently working on a project the requires the use of WebParts to allow a user to construct custom reports by dragging and dropping WebParts into WebPartZones. I needed to dynamically create these WebParts on the fly and add them to the page programmatically. I tried to do this by using the standard AddWebPart() method of the WebPartManager control but found that using this method the WebPart doesn’t seem to be added to the page correctly which seems to be because the AddWebPart() methods gives the WebPart a random ID therefore it cannot participate in ViewState management. Furthermore because of the need to add the WebPartZones within the Page OnInit event the WebParts were getting recreated each time the page did a postback.

I searched around the web and found lots of people having the same problem but very little in the way of solutions to the problem. Eventually I stumbled across a forum post that mentioned the WebPartManagerInternals class. The documentation fails to mention exactly how to use this class but contained the following text:

“Isolates into a separate class methods that are used by the WebPartManager control and can be overridden by developers who extend the control, but are rarely needed by page developers.”

It also mentions that the class is a sealed class meaning you cannot derive from it and a quick look in Reflector showed me that it’s contructors were internal. This meant I needed to access the class from within the WebPartManager class.

I created a new DynamicWebPartManager class that derived from WebPartManager and in this class I created a method called AddDynamicWebPart(WebPart webPart, WebPartZone zone) which as you can see accepts a WebPart and a WebPartZone. In this method I called two methods on the Internals property (beware this Internals property DOE’S NOT show up in Intellisense) AddWebPart() which accepts a WebPart and SetZoneID() which tells it which WebPartZone to add the WebPart to.

public class DynamicWebPartManager : WebPartManager
{
public void AddDynamicWebPart(WebPart webPart, WebPartZone zone)
{
Internals.AddWebPart(webPart);
Internals.SetZoneID(webPart, zone.ID);
}
}

Now by using this DynamicWebPartManager class on your page instead of the out of the box WebPartManager class you can add WebParts by calling the AddDynamicWebPart() method.

WebPartZone reportZone = new WebPartZone();
reportZone.ID = “reportZone1″
reportZone.HeaderText = “My Report”;
ToolBoxPanel.Controls.Add(reportZone);

TestTableWebPart webPart = new TestTableWebPart();
webPart.ID = “webPart1″
webPart.Title = “My Report - Table”;
ReportBuilderWebPartManager.AddDynamicWebPart(webPart, reportZone);

kick it on DotNetKicks.com

Scott Guthrie’s presentation on new MVC Framework

October 12, 2007

Scott Hansleman posted this video recorded from a recent ALT.Net conference.

Scott Guthrie demo’s the new MVC Framework from Microsoft which uses the MVC Front controller pattern that Ruby on Rails people would be familar with.

I definately recommend watching the presentation it’s 60 minutes long but well worth it.

I’m undecided on the Framework yet until I get to play with it, but I do know that introducing a more disiplined, structured way of developing web applications with .Net is a good thing.

Creating a Templated User Control with ASP.Net 2.0

August 11, 2007

We all know the benefits of re-usable components in our applications and User Controls in ASP.Net are an easy way to build reusable components that can be used throughout an entire web application.

Templated User Controls allows us to seperate the controls data from it’s presentation because a Templated User Control does not provide a default user interface.

For example I will show you how to create a templated address control thats allows you to reuse address fields across your web application but leaves the formatting up to the individual page designer to style how they wish.

First we open a new web application in Visual Studio and add a new Web User Control to our solution.

We then add a PlaceHolder control to the User Control which will act as a placeholder for our controls rendered data. Our controls markup looks like this:

Next we switch to our controls code behind and implement all the properties we need for our address control plus one other property that returns a type of ITemplate. Our code behind looks like this:


Now we need to create a container class that will act as our naming container and exposes all the properties of the User Control to the host page. The container class needs to inherit from the Control class and implkements the INamingContainer interface. The class looks like this:

We need to put the following code inside out controls Init event to instantiate our container class and set its properties, instantiate a copy of the controls ITemplate inside the container control and add our container control to the PlaceHolder’’s controls collection.

Now we have a fully working Templated User Control we can put this control onto any web page within out web application and set its data. The markup below shows how this is done:

And thats it!

If you want to do the same as this but package the control up into an assembly that can be reused across multiple web applications you need to create a control that inherits from the Control or WebControl class.

kick it on DotNetKicks.com

Multithreading with ASP.Net 2.0

July 22, 2007

Every good developer should understand the basics of how Threads and Processes work on the platform they are writing applications for.  For us it’s the Windows operating system and using the .Net Framework it’s even easier to harness the power of Multithreading.

Good Multithreading design can vastly improve your applications user experience and I have a little example below of how Multithreading can be used within an ASP.Net 2.0 website.

Our goal here is to send a request to the server and write out 101 lines to a text file on the webserver.  The WriteOutTextFile() method takes a very long time to complete as I have deliberatly made the method run slow by making the thread go to sleep for 500ms every iteration of the loop.  Now say this method was used as a logging tool behind the scenes, we wouldn’t want our user waiting for the method to write out all 101 lines before the web page was returnd to them. The user doesn’t care that your logging method takes a long time they just want to see their request returned to them, this is where multithreading comes in. We open up a new web site in Visual Studio and we have a simple application as shown below:

I put one label and one button on the form and our markup looks like this:

We then switch to our code behind and write the following code in the OnLoad event:

Here the first thing we are doing is setting the label’s text property to “PostBack!” which is pretty standard stuff, the interesting part is the next four lines.   In version 2.0 of the .Net Framework multithreading was made so much easier by introducing the ThreadStart class which allows us to easily pass the method we want to be called when our threads starts to the Thread class.  The ParameterizedThreadStart class makes things even easier when you want to pass arguments to your methods and anyone who has done multithreading in .Net 1.1 knows how much of a headache this was. So what we are doing in these four lines is creating an instance of the ThreadStart class to tell our new thread to call our worker method WriteOutTextFile when we start out new thread. We then go ahead and create our new Thread and call it’s Start() method. This will kick off our WriteOutTextFile() method on a new thread and allow the OnLoad event to finish execution and return our request back to the user.  Our new thread will continue executing and writing to our text file in the background. The WriteOutTextFile() method looks like this:

That’s a simple example of how multithreading can be used to good effect with the .Net 2.0 framework.  As you can see it’s a very powerful tool and mastering multithreading can make your applications more performant, much more scalable and give your end user and less frustrating experience. I have uploaded the source code here, if you want to download and anaylse it yourself.

kick it on DotNetKicks.com

Data Access Layer version 1.1 released

May 13, 2007

I have uploaded a new page to this site which will host my data access layer project. I have used this data access layer in a few production systems now and it has proved to be a valuabe tool and increased my productivity no end by allowing me to forget about writing data access code over and over again.

 I have released the object library under the GNU public licence so the source code is freely available for you to download and use.

 Visit the Data Access Layer page here and let me know your comments.

Refactoring with Visual Studio 2005 - Encapsulate Field

May 8, 2007

One of the basic principles of object oriented programming is ‘Encapsulation’, and to me one of the fundamental ways to acheive encapsulation when creating classes is to only allow access to it’s private members through public accessor methods.

For example using C# I create the following class:

public class LeeClass

    {

        public String _name;

    }

 

 

The problem with this code is it directly exposes the classes data to the outside world and this breaks the encapsulation rules of OOP.

What we need to do to allow the outside world access to this variable is define a public accessor method which effectively ‘encapsulates’ the variable.

We can code this by hand but Visual Studio provides you with a handy refactoring function that handles all the work for you.

Do the following

Right click on the _name variable and select Refactor -> Encapsulate Field as show below.

Refactoring - Encapsulate Field

You will now be presented with a dialog box which allows you to give your new method a name.  You can also from here select the ‘External’ option in the ‘Update References’ option group which will update all references to your variable to point to your new accessor method.

You show now have a class that looks like this

public class LeeClass

    {

        private String _name;

 

        public String Name

        {

            get { return _name; }

            set { _name = value; }

        }

    }

 

 

Notice how Visual Studio changes your publicly exposed variable to private and inserts get/set methods to access it.

 

You now have a class that conforms to the encapsulation principle of object oriented programming.