Setting a Site’s locale in SharePoint using SPLocale class.

A requirement I came across recently was to write a tool to set a site’s locale from US to UK using the object model.  Because I potentially needed to do this for hundreds of sites I opted to write a small command line tool that can be scripted to help with the task.

Below is an overview of how to use the SPLocale class to set the Locale of a site.  I have also provided download links for the compiled command line tool and its source code for you to take a look at.

First thing we need to do is grab an instance of the site:

SPSite site = new SPSite(“localhost”);

 

Next thing we do is get a collection of all the web sites under your site:

 

SPWebCollection webCollection = site.AllWebs;

 

We can now interate over this collection and set the Locale property to your new locale which will be an instance of the CultureInfo class. We create a new instance of the CultureInfo class by passing the new Locale’s LCID value to it’s constructor.

 

foreach (SPWeb web in webCollection)

{

      web.Locale = new System.Globalization.CultureInfo(2057);

      web.Update();

}

 

Thats basically all there is to it.

 

Downloads:

 

Excecutable - http://www.athousandthreads.com/blog/code/SPSiteLocaleExe.zip

 

Source Code - http://www.athousandthreads.com/blog/code/SPSiteLocaleSource.zip

 

Example of command line:  SPSiteLocale.exe set http://localhost 2057

 

 

Microsoft Release SharePoint Administration Toolkit

Microsoft has announced their first release of the SharePoint Administration Toolkit over at the SharePoint Products and Technologies Team Blog.

This toolkit provides some cool new features which some MOSS 2007 admins might find very handy.  One such feature is the ‘Batch Site Manager’ which give admins the ability to schedule bulk operations against site collections.

There is a whitepaper up on MSDN which give you more information on the toolkit and detailed steps for installation.

Download links for the toolkit:

 x86: http://www.microsoft.com/downloads/details.aspx?FamilyId=263CD480-F6EB-4FA3-9F2E-2D47618505F2&displaylang=en

x64: http://www.microsoft.com/downloads/details.aspx?FamilyId=F8EEA8F0-FA30-4C10-ABC9-217EEACEC9CE&displaylang=en

Programmatically removing all WebParts from a page in MOSS 2007

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.

Open university course update.

I started the M150 Open University course back in September and have just got the results back on my second course assignment.

My result for my first assignment was 77% and the result for the second assignment was 88% so thankfully things are getting better not worse!

I must say I do find it difficult to find the time to sit down for a few hours and go through the course material and complete the assignments. I also find it it’s harder to understand what specific things the question is asking you to write than actually understanding the concepts it’s trying to teach.

Although I am learning little bits here and there I’m not really finding the course material challenging at the moment which I kind of expected.

Anyway hopefully I’ll get a better mark for the next assignment which is due 22nd Feb, it looks like most of the assignment is writing out Javascript code so hopefully I won’t find it too difficult.

Visual Studio 2008 UK Launch Event

I’m now registered to attened the UK launch event for Visual Studio 2008 which is happening at the ICC in Birmingham on the 19th March.

There are two tracks for this event the IT pro track and the developer track, make sure you register the right track as you cannot change this after.

You can read more about the events over at http://www.microsoft.com/uk/heroeshappenhere/default.mspx

And you can register yourself here https://msevents.microsoft.com/cui/EventDetail.aspx?culture=en-GB&eventid=1032366502

Should be a good event, will definately feed back on how it went.

I’m Twittering

I signed up to twitter a while back but never got around to actually using it.

I thought I might as well give it a go and start twittering so I downloaded twitterberry for my blackberry mobile which is a great little app for updating twitter on the move.

If you want to follow my updates my username is leedale

Dynamically adding WebParts using WebPartManagerInternals class

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

Downgrading iPod Touch 1.1.2 and installing iPhone apps

This Christmas Santa brought me a nice 16GB iPod Touch which I’ve been after for a while now. Out of the box the iPod Touch is brilliant it does everything you would expect of an iPod and more, however the geek in me wanted to see if there was any third party applications that I could install. After searching around the net for a while I came across http://jailbreakme.com which basically installs and application that allows you to download and install third party apps straight from your iPod Touch. Great I thought but there was one problem, my iPod came out the box with version 1.1.2 of the firmware and wouldn’t allow me to install the AppSnap application.

After more searching around I settled on the fact that I needed to downgrade my firmware to version 1.1.1 if I was going to jailbreak the iPod. There is a way to upgrade back to firmware 1.1.2 after jailbreaking your iPod but I didn’t see the point as there wasn’t much difference between the two versions plus I read a few places that certain application wouldn’t work with version 1.1.2 anyway.

Below is a step by step guide on how to first downgrade your iPod Touch to version 1.1.1 then install Mail and Maps apps from the iPhone, bear in mind that this is not supported by Apple and I will not be responsible for any damage that happens to your iPod. Also the restore WILL ERASE everything on your iPod and restore it to it’s factory settings.

One more thing to note is this step by step guide is being done on a Mac so certain steps may be slightly different for Windows, but any half tech savvy user should be able to make it work on Windows.

My iPod Touch looked like this out of the box, as you can see version 1.1.2 of the firmware is installed.

  • The first thing you need to do is to download firmware 1.1.1 to your computer, the file is around 150Mb. You can get it from here: http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPod/SBML/osx/bundles/061-3932.20070927.p23dD/iPod1,1_1.1.1_3A110a_Restore.ipsw
  • The next step is to connect your iPod Touch to your computer with the USB cable.
  • Open up iTunes if it’s not open already (I’m using version 7.5) and on the main iPod screen hold down the Option key on Mac and click Restore. You should get an Open File dialog from which you can select the 1.1.1 version of the firmware you downloaded earlier.
  • iTunes should now extract your firmware and begin restoring your iPod, follow the on screen instructions and wait until your iPod is fully restored and shows back up in iTunes with version 1.1.1. Don’t worry if the restore errors just keep trying it and it will eventually work. After your iPod is fully restored you should see the new firmware installed from the settings -> about menu.

  • On your iPod open Safari, navigate to http://jalbreakme.com , scroll down to the bottom of the screen and click Install AppSnap. Safari should now close itself, the application should install and the iPod should then restart itself.
  • Once your iPod has restarted you should see an extra application on your springboard called Installer. From here you can start installing third party applications direct to your iPod.

Now your iPod is open we can begin installing the iPhone apps. Currently only the Mail and Maps applications work on the iPod so i’ll show you how to install these.

  • You need to download the iPhone apps from here http://rs75.rapidshare.com/files/61867543/iPhone_1.1.1_Apps.zip to your computer. Once downloaded unzip the files to a folder on your machine.
  • We now need a way to transfer these applications to your iPod we do this by using an SFTP client from out computer. On the Mac I’m using Cyberduck which is a free download.
  • On the iPod we need to install OpenSSH which allows us access to the iPod file system, OpenSSH relies on the BSD Subsystem package so we first need to install this on our iPod. Open the Installer app on your iPod and goto Install. Click All Packages and scroll down to BSD Subsystem. Click on Install and wait for the package to be installed.
  • Now we have the BSD Subsystem installed we can install OpenSSH so do the same as above but scroll down to the OpenSSH package and install that.
  • Open up Cyberduck or whatever SFTP client you are using and connect to your iPod’s IP address which can be found by going to Settings -> WiFi and clicking the little blue icon next to your wireless connection. The username and password you need to use is: username = root, password = alpine.
  • Now you have an open SFTP connection to your iPod you can begin copying the iPhone files across. Start with copying the GMM.Framework folder to /System/Library/Frameworks/
  • Now copy the Maps.app to the /Applications/ folder.
  • We now need to open an SSH connection to your iPod so we can alter the permission settings for Maps.app. If you’re on Mac simply open a Terminal window and type

    SSH [enter your iPods IP address] –l root

    You will be prompted to enter a password, enter alpine and press enter.

  • Now enter the command:

    Chmod a+x /Applications/Maps.app/Maps/

    After a restart the Maps application should now work.

  • Now to install Mail you need to copy MobileMailSettings.bundle to /System/Library/PreferenceBundles/ and MobileMail.app to /Applications.
  • Now to set the permissions for Mail we need to SSH onto the iPod again and run the following command:

    Chmod R a+x /Applications/*

And thats it! Now you should have Maps and Mail running on your iPod plus be able to download some great third party apps from the Installer application.

Have a Merry Xmas everyone

Well it’s that time of the year again, Christmas Eve!

Just wanted to wish everyone a Merry Xmas and a Happy New Year hope everyone has some time off relaxing with family and friends.

I’m off work until 2nd Jan but I’ll be spending most of that time finishing off my second assignment paper which is due in January.

Have a good holiday!

Creating a Tableless LoginControl with ASP.Net 2.0

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

Next Page »