Archive for the '.Net' 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

Creating a Tableless LoginControl with ASP.Net 2.0

November 17, 2007

The trouble with using some of the built in .Net controls like LoginControl and TreeView is that they render their output in tables and as we know tables should only be used to display tabular data not control the layout of a web page.

If we wanted to write semantic markup and style our web pages so they have proper accessible output we need to override the way ASP.Net controls render their HTML.

One way of doing this is using the CSS friendly control adapters which come with a number of built in controls for changing the rendered output of certain ASP.Net controls. Using these controls you can completely alter the way each ASP.Net control renders its output to the browser. The drawback here is that you need to reference another assembly and write .Net code if you need to modify anything.

The LoginControl supplies you with a nice ContentTemplate section that allows you to control the rendered output directly in the markup.

The following ASP.Net and CSS demonstrates how to create a tableless LoginControl. I apologise for the code formatting, it seems no matter what I do wordpress doesn’t like code :(. Best thing to do is copy and paste into a proper editor window to see what I’ve done.

Markup:

<div id=”Registration”>
<asp:CreateUserWizard ID=”CreateUserWizard1″ runat=”server”>
<WizardSteps>
<asp:CreateUserWizardStep ID=”CreateUserWizardStep1″ runat=”server”>
<ContentTemplate>
<h1>Sign Up for Your New Account</h1>
<div id=”Security”>

<span class=”FormLabel”>
<
asp:Label ID=”UserNameLabel” runat=”server” AssociatedControlID=”UserName”>User Name:</asp:Label>
</span>
<span class=”FormControl”>
<asp:TextBox ID=”UserName” runat=”server”></asp:TextBox>
<
asp:RequiredFieldValidator ID=”UserNameRequired” runat=”server” ControlToValidate=”UserName”
ErrorMessage
=”User Name is required.” ToolTip=”User Name is required.” ValidationGroup=”CreateUserWizard1″>*
</asp:RequiredFieldValidator>
</span>
<span class=”FormLabel”>
<
asp:Label ID=”PasswordLabel” runat=”server” AssociatedControlID=”Password”>Password:</asp:Label>
</span>
<span class=”FormControl”>
<asp:TextBox ID=”Password” runat=”server” TextMode=”Password”></asp:TextBox>
<
asp:RequiredFieldValidator ID=”PasswordRequired” runat=”server” ControlToValidate=”Password”
ErrorMessage
=”Password is required.” ToolTip=”Password is required.” ValidationGroup=”CreateUserWizard1″>*</asp:RequiredFieldValidator>
</span>

<span class=”FormLabel”>
<
asp:Label ID=”ConfirmPasswordLabel” runat=”server” AssociatedControlID=”ConfirmPassword”>Confirm Password:</asp:Label>
</span>
<span class=”FormControl”>
<
asp:TextBox ID=”ConfirmPassword” runat=”server” TextMode=”Password”></asp:TextBox>
<
asp:RequiredFieldValidator ID=”ConfirmPasswordRequired” runat=”server” ControlToValidate=”ConfirmPassword”
ErrorMessage
=”Confirm Password is required.” ToolTip=”Confirm Password is required.”
ValidationGroup=”CreateUserWizard1″>*
</
asp:RequiredFieldValidator>
</span>
<span class=”FormLabel”>
<
asp:Label ID=”EmailLabel” runat=”server” AssociatedControlID=”Email”>E-mail:</asp:Label>
</span>
<span class=”FormControl”>
<asp:TextBox ID=”Email” runat=”server”></asp:TextBox>
<
asp:RequiredFieldValidator ID=”EmailRequired” runat=”server” ControlToValidate=”Email”
ErrorMessage
=”E-mail is required.” ToolTip=”E-mail is required.” ValidationGroup=”CreateUserWizard1″>*</asp:RequiredFieldValidator>
</span>
<span class=”FormLabel”>
<
asp:Label ID=”QuestionLabel” runat=”server” AssociatedControlID=”Question”>Security Question:</asp:Label>
</span>
<span class=”FormControl”>
<asp:TextBox ID=”Question” runat=”server”></asp:TextBox>
<
asp:RequiredFieldValidator ID=”QuestionRequired” runat=”server” ControlToValidate=”Question”
ErrorMessage
=”Security question is required.” ToolTip=”Security question is required.”
ValidationGroup=”CreateUserWizard1″>*</asp:RequiredFieldValidator>
</span>
<span class=”FormLabel”>
<
asp:Label ID=”AnswerLabel” runat=”server” AssociatedControlID=”Answer”>Security Answer:</asp:Label>
</span>
<span class=”FormControl”>
<asp:TextBox ID=”Answer” runat=”server”></asp:TextBox>
<
asp:RequiredFieldValidator ID=”AnswerRequired” runat=”server” ControlToValidate=”Answer”
ErrorMessage
=”Security answer is required.” ToolTip=”Security answer is required.”
ValidationGroup=”CreateUserWizard1″>*</asp:RequiredFieldValidator>
</span>
<span class=”FormLabel”>
<
asp:CompareValidator ID=”PasswordCompare” runat=”server” ControlToCompare=”Password”
ControlToValidate
=”ConfirmPassword” Display=”Dynamic” ErrorMessage=”The Password and Confirmation Password must match.”
ValidationGroup=”CreateUserWizard1″></asp:CompareValidator>
</
span>
<span class=”FormControl”>
<
asp:Literal ID=”ErrorMessage” runat=”server” EnableViewState=”False”></asp:Literal>
</span>
</div>
</ContentTemplate>
</asp:CreateUserWizardStep>
<asp:CompleteWizardStep ID=”CompleteWizardStep1″ runat=”server”>
</asp:CompleteWizardStep>
</WizardSteps>
</asp:CreateUserWizard>
</div>

 

CSS:
#Security
{
margin-top: 10px;
width: 60%;
text-align: left;
border: dashed 1px #999999;
padding: 20px;
background-color: #f9f9f9;
}

#Registration
{
margin-top: 5px;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 70%;
font-size: 1.2em;
}

#Registration h1
{
margin-top: 20px;
margin-bottom: 20px;
}
#Registration
input, textarea
{
width: 180px;
margin-bottom: 5px;
}

.Boxes
{
width: 1em;
}
.FormLabel
{
float: left;
width: 120px;
font-weight: bold;
}
.FormControl
{
float: left;
width: 45%;
}

This should provide you with a nicely formatted form that is rendered using DIV’s and SPAN’s rather than in a TABLE. You should now be able to style the markup and control layout better to provide your end users with a more accessible web page.

kick it on DotNetKicks.com

Disposing Windows SharePoint Services objects

October 22, 2007

I came accross this article on MSDN about disposable WSS 3.0 objects. I recommend anyone working with the SharePoint object model to give this article a thorough read.

The article outlines the fact that the two main classes in the object model SPSite and SPWeb both use unmanaged code and without proper disposal can seriously harm the performance of your SharePoint site.

Both these classes implement the IDisposable interface and best practice with .Net code generally is if a class exposes a Dispose method then you should always call that Dispose method to clean up any unmanaged resources the object might have used.

Not adhering to this best practice when using the SharePoint object model can hurt the performace of your site quite badly and when you realise how much more memory the unmanaged part of the object consumes compared to the managed part you will soon realise how important cleaning up them unmanaged reasources is.

Anyway the article goes into more depth so get over to MSDN and have a read.

http://msdn2.microsoft.com/en-us/library/aa973248.aspx

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

Supressing Postbacks with ASP.Net 2.0 TreeView control

July 4, 2007

I’m working on a project at the moment that requires a navigation menu built with ASP.Net 2.0. The requirements dictate that the navigation elements should be configured in an XML file. This sounded perfect for the ASP.Net siteMap provider so I set about implementing a SiteMapDataSource and binding a TreeView control to it.

This worked fine however each top level menu item had to be collapsable with a ’scrolling’ animation and this was implemented using jquery. The only thing was, I didn’t want a postback to occur when the user clicked on each menu item which is the default action with the TreeView control.

In ASP.Net 1.1 you could set AutoPostBack property of the TreeView control to false and this would supress postbacks for every node. This property is missing in ASP.Net 2.0 so I set about finding a solution to the problem. Unfortunately there wasn’t much on the web about how to solve this particular problem but I did end up finding a solution that worked a treat.

For every node in the TreeView who you don’t want to cause a postback you should set it’s NavigateUrl property to javascript:void(0);

Now when a user clicks on the node a postback will not occur which is exactly what I needed.

DDD5 at Microsoft TVP Reading

July 1, 2007

Yesterday I traveled to Microsoft’s campus in Reading for the fifth Developer Day event and I must say I was very impressed with the presentations and the organisation of the whole thing.

The first presentation I attended was IIS7 for ASP.Net developers. IIS7 as the presenter Andrew Westgarth said is definitely the most significant release since version 1.0 and really puts the power of the Microsoft web server in the .Net developers hands. It’s highly customizable with .Net, gets rid of the need for writing ISAPI filters and falls in line with the .Net configuration model utilizing XML configuration files extensively. Also as Andrew pointed out it’s the first time the version of IIS is the same on the desktop as it is on the server, so you get the same features on Vista as you would on Server 2008. The only restriction on Vista is a maximum of 10 simultaneous requests, which nobody doing development should ever notice.

The second presentation I attended was Visual Studio 2005 IDE Tips and Tricks presented by Guy Smith-Ferrier. I wanted to attended this because I always say to myself I’m going to learn the short cuts in VS and never get round to actually doing it so this presentation gave me alot of pointers that I could go away and use in my daily work and hopefully improve my productivity. There was alot stuff that I already knew which was inevitable but I got a good few gems out of it which is what I was looking for.

Now the third presentation was An Appraisal of Object Thinking which was presented by Alan Dean. The presentation was essentially talking about the concepts outlined in the MS Press book Object Thinking. The author of the book is basically saying that our formalized perception of Object Oriented Programming is not how the founders of the term OOP intended for it to be used. I won’t go into detail of the concept as you can always buy the book or check Alan’s blog for the presentation slides but I did eventually come round to the new way of thinking and can actually see the benefits it would bring. The only thing is that everyone you are collaborating with on a programming project would also have to buy into the concept and that wouldn’t be an easy thing to do, as it’s hard to change people ways but none the less it was good to get another perspective on OOP as we all nowdays take the concept for granted and we all conform to the standard way of developing objects.

The last presentation I attended was Agile Methods for ISV’s presented by Gary Short. Gary’s presentation was very good and he has a good way of getting his point accross and was very humorous so I did actually enjoy the presentation alot. Gary basically outlined the pro’s and con’s of implementing an agile methodology in ISV’s and Enterprise’s.

I didn’t attained the last presentation as I had to shoot off but would just like to say thanks to the organizers and the presenters on the day who did a fantastic job and can’t wait for the next installment keep up the good work.

Just passed Microsoft Exam 70-310!

June 16, 2007

Well this morning I took the Microsoft Exam 70-310 entitled ‘Developing XML Web Services and Server Components with Visual Basic .Net and the .Net Framework’. I’m glad to say I passed despite feeling a bit worse for wear this morning (one too many pints last night) and can now move onto the next one on my list which is 70-229 Designing and Implementing Databases with Microsoft SQL Server 2000 Enterpise Edition.

After passing the SQL Server exam I will be an MCAD, I was debating whether to take the last exam and go for MCSD but to be honest I want to move onto MCTS and MCPD as the .Net 1.1 exams are rapidly becoming out of date.

I’m off on holiday to Cancun next Tuesday and with no studying to do and no contract at the moment I can sit back and relax for a couple of weeks before diving into my next bit of work.

EDIT: After looking at my transcript in the MCP area, it turns out doing exams 70-305, 70-315 and 70-310 is enough to acheive MCAD status, so there you have it, I’m now an MCAD! No need to do exam 70-229 (as it’s becoming rather dated), I’ll move onto upgrading my MCAD to MCTS and MCPD by taking the upgrade exam 70-551.