Archive for the 'SharePoint' Category

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.

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

Disposing Windows SharePoint Services objects

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

Deploying a WebPart Solution in SharePoint 2007 the simple way

Deploying web parts into MOSS 2007 isn’t exactly straight forward and after looking around the web for a while it became apparent that there is no ’standard’ way for deploying them. I looked at a few different options and found that creating a Solution file using Visual Studio’s CAB Setup Project was the easiest and most reusuable way of accomplishing this task.

Below is a step by step guide to developing and deploying a simple WebPart.

First we need to create a WebPart to deploy, the easiest way I have found of doing this is to download the Visual Studio SharePoint extensions from Microsoft which can be located here.

After installing the extensions open Visual Studio and create a new project. You should now have some extra project templates under the SharePoint section.

Select ‘Web Part’ project, give it a name and click OK.

Visual studio will now create a basic Web Part class for you to edit.

My Web Part was called ClientViewerWebPart and I inserted some code into the overridden Render method which basically outputs data from a SharePoint list. This code looks like this so far:

 

using System;

using System.Runtime.InteropServices;

using System.Web.UI;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Serialization;

using Microsoft.SharePoint;

using Microsoft.SharePoint.WebControls;

using Microsoft.SharePoint.WebPartPages;

 

 

namespace ClientViewerWebPart

{

    [Guid("6bf05a67-118d-4cc4-80f7-b923be02773a")]

    public class ClientViewerWebPart : System.Web.UI.WebControls.WebParts.WebPart

    {

        public ClientViewerWebPart()

        {

            this.ExportMode = WebPartExportMode.All;

        }

 

 

        protected override void Render(HtmlTextWriter writer)

        {

            SPSite site = new SPSite(“http://leesbs/”);

            SPWeb web = site.OpenWeb();

            SPListCollection collection = web.Lists;

            SPList list = collection.GetList(new Guid(“{936518FF-CC2E-4BD9-ABB9-0580EA04BCD6}”),                         false);

 

            for (int index = 0; index < list.Items.Count; index++)

            {

                SPListItem item = list.Items[index];

                writer.Write(“<table>”);

                writer.Write(“<tr><td>Client Name</td>”);

                writer.Write(“<td>” + item["Client Name"].ToString() + “</td></tr>”);

                writer.Write(“</table>”);

            }

        }

    }

}

Next we need to tell SharePoint to allow this web part to be executed from a partially trusted location. We do this by making an entry into the web parts AssemblyInfo file.

In Solution Explorer Expand Properties and open up the AssemblyInfo.cs file. At the bottom of the file insert the following:

[assembly: System.Security.AllowPartiallyTrustedCallers()]

Now we need to add a manifest file to out Web Part project. This manifest file is what defines our solution and tells SharePoint everything it needs to know about our Web Part.

Add a new XML file to tthe project and rename it manifest.xml. Insert the following XML into the file:

<?xml version=1.0 encoding=utf-8 ?>

    <Solution xmlns=http://schemas.microsoft.com/sharepoint/

                    SolutionId={E3CF88A3-0EC3-49b9-B09E-5F84417EC6ED}>

        <Assemblies>

            <Assembly DeploymentTarget=WebApplication

                                  Location=ClientViewerWebPart.dll>

                <SafeControls>

                    <SafeControl Assembly=ClientViewerWebPart, Version=1.0.0.0, Culture=neutral,                                                                                         PublicKeyToken=3858ebd08dca7ee0

                                            Namespace=ClientViewerWebPart TypeName=*/>

 

                </SafeControls>

        </Assembly>

    </Assemblies>

</Solution>

 

You need to provide your own GUID value for the SolutionId attribute, you can do this within Visual Studio by using the GUID Generator under the Tools menu. You also need to enter your assemblies PublicKeyToken value which can be found by either using ILDASM.exe or Reflector.

 

The last thing we need to do to our Web Part project is make sure it has a strong name when it’s compiled, you can do this either using the SN.exe command line tool, or opening the project properties from within Visual Studio and navigating to the Signing section. From here you can create a new key file which will be used to strong name the assembly at compile time.

 

Now we have a fully working Web Part which can be compiled, what we need to do now is deploy this Web Part into our SharePoint site.

 

We are going to use a Visual Studio setup project to accomplish this, so add a new project to the same solution your Web part project is in, and create a CAB setup project. I called my setup project ClientViewerWebPartSetup.

 

Right click on the project and goto Add -> Project Output, from the ‘Add Project Output Group’ dialog box, select your Web Part project and then select ‘Primary Output’.

 

Repeat the step above but this time instead of selecting ‘Primary Output’ select ‘Content Files’.

 

After this is done you should have a solution that looks something like this:

 

 

Now you can compile your setup project, this will create a cab file containing the WebPart assembly and the manifest.xml file so all we need to do now to create our SharePoint solution file is rename our .cab file to .wsp.

 

We are now ready to deploy this solution file into SharePoint and we do this by using the STSADM.exe tool. This tool is located in your SharePoint installation directory under the bin folder mine was located here C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN. I strongly suggest you add this path to you PATH environment variable for ease of use.

 

You need to use the addsolution argument to the STSADM tool the first time you deploy a Web Part into your SharePoint site. When updating the Web Part you can use the upgradesolution argument.

 

The following is how I deployed my Web Part into my SharePoint site for the first time.

 

 

Great! Your Web Part is now deployed into your SharePoint site, or is it?

 

We need to do one more thing to make out Web Part available to our SharePoint site.

 

Open up Central Administration and navigate to ‘Operations’ under ‘Global Configuration’ click ‘Solution Management’. You should see your Web Part Solution sitting in the list with ‘Not Deployed’ as it’s status. Click on the Solution and click the ‘Deploy Solution’ button.

 

You should now be able to add your Web Part to any sites Web Part gallery.

 

Hope this guide has been useful, it’s quite a lengthly process do first time, but should get easier the more times you do it.

 

kick it on DotNetKicks.com

Forms Based Authentication with SharePoint 2007

A while back I spent a few weeks at Microsoft Campus working for a client on a MOSS 2007 proof of concept project. One of my jobs was to get FBA working alongside Windows Authentication on the same site. After reading a few excellent blog posts namely Nick Swan’s and Dan Attis and getting FBA partially working it became apparent that FBA with SharePoint is a bit of a ‘gray’ area and alot of people are struggling with it. I also sat with a Microsoft guy who specialised in SharePoint who had never even seen FBA working with the SSP profile database before.

I want to write about a couple of issues I came across when working within SharePoint and FBA, I won’t go into detail with the actual setup because the above mentioned blog posts cover most or all of what you will need to do.

The first one is this, if you use the Visual Studio’s Website configuration tool to add your Forms Based users, be careful because it modifies your web sites web.config file and adds xmlns=”http://schemas.microsoft.com/.NetConfiguration/v2.0″ as an attibute to the <configuration> section. I don’t actually kow of a workaround for this but if you don’t delete this attibute your will be greeted with a File Not found error from your SharePoint site.

Another issue I came across was even though I had setup my site for FBA correctly, central admin was still not resolving my FBA users at all. After running SQL Profiler against the database I realised that the ASP.Net membership database stored procedures were being called with an application id, now this is where it gets a bit confusing. You need to run the Visual Studio Admin tool against the SharePoint 80 web site, but Central Admin runs in it’s own virtual directory therefore has a different application id. Now I’d love to know if I was doing something wrong or if there is a workaround for this, but in the end due to a tight timescale I had to hand modify the ASP.Net stored procs to not filter application id’s.

Hope this information is useful as it became apparent that FBA in SharePoint is a bit of a ‘hit or miss’ technology and is not as easy as it should be to setup out of the box.

Would be glad to hear from anyone who has had similar problems and found an easier way round it.


A Thousand Threads Logo
View Lee Dale's profile on LinkedIn

    Archives