Monthly Archives: August 2009

SharePoint 2010 – Hints, Tips and New Features – Watch this Space!

Well, the SharePoint Conference is just around the corner, and information about SharePoint 2010 will start seeping out of the woodwork soon enough!
 
Now, there is nothing that I can tell you now (there are heavy restrictions on the Non Disclosure Agreement we have with Microsoft) but I will be keeping my finger very much on the pulse and aim to start bringing out blog posts about the new functionality in SharePoint 2010 as soon as the NDA is lifted!
(no .. I will NOT release ANY information until officially sanctioned by Microsoft .. so please don’t ask!)
 
I expect new materials will become "public knowledge" after the SharePoint Conference so hopefully I’ll be able to start sending out tit-bits soon after that.
You can expect blog posts about:
 
  • Development – Code examples and Walkthroughs
  • New Features – new functionality and areas of the SharePoint 2010 product
  • Hints and Tips – tricks and "didn’t know that .." information about the new build, and my experience with it once it becomes available.
So … watch this space! Boy am I looking forward to the next 12 months!!

SharePoint Timer Jobs and Multiple Servers

Timer jobs are wonderfully robust creatures. They effectively replace the "Windows Scheduled Task" for SharePoint servers, allowing you to run .Net code on a scheduled or "one off" basis.

However, there can be some confusion about running Timer Jobs on multiple servers, so this should clear it up a bit.

  1. By default Timer Jobs will only execute on the server that they are called from (typically the Central Administration server)
  2. Through code you can specify a specific box (SPServer) to run your Timer Job on.
  3. It is possible to run a Timer Job on every server on the farm (although this can be dangerous!)

The crux of all this is based on the SPJobDefinition constructor (https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spjobdefinition.spjobdefinition.aspx).

The constructor includes a parameter for an SPServer object, which allows you to specify which server the timer job will run on.

Example Code 1 – Add Job to single Server:

The code below is for a Web Application scoped which will register a job definition on a single server. As Web Application scoped features are activated from Central Administration, it will use the current SPServer (i.e. the Central Admin server).

This is useful for code which modified content in the database, as you only want it to execute a single time.

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;

SPJobDefinition job = new SPJobDefinition("CustomJobDef", webApp);

}

Example Code 2 – Add Job to All Servers:

The code below is for a Web Application scoped which will register a job definition on all web front end servers in the farm.

This is useful for code which modifies files or server settings, as you need it to execute separately for each server.

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;

foreach (SPServer server in SPFarm.Local.Servers)

{

if (server.Role == SPServerRole.WebFrontEnd)

{

SPJobDefinition job = new SPJobDefinition("CustomJobDef", webApp, server, SPJobLockType.None);

}

}

}

Hope this helps! Enjoy!

Turning off Audience Targeting on Page Libraries – Operation is not valid due to the current state of the object

Well .. this took a while to crack.
 
"Operation is not valid due to the current state of the object"
 
Anyone who has seen this will know it’s a pain to track down. This particular one was even more painful that usual, because it was being thrown from the "Modify Audience Targeting" page of a Pages Library in MOSS 2007!
 
Do I did some rooting around and found a great post from Gary Lapointe (https://stsadm.blogspot.com/2008/08/enabling-audience-targeting-on-list.html) showing how to enable (or disable) audience targeting on a list through code.
 
However, there was a bug so it gave me the same error message!
The problem is that the field that we are trying to delete (Audience Targeting) is Sealed. So you need to set "Sealed=False" .. (I also set "AllowDeletion=True" as well to be on the safe side!)
 
The working code (modified from Gary Lapointe’s original code) is as follows:
 
public static void SetTargeting(SPList list, bool enabled) 
        {  
                if (list == null) 
                    throw new SPException("List was not found."); 
               
                SPField targetingField = GetTargetingField(list); 
                if (enabled && (targetingField == null)) 
                { 
                    string createFieldAsXml = CreateFieldAsXml();
                    list.Fields.AddFieldAsXml(createFieldAsXml); 
                    list.Update(); 
                } 
                else if (!enabled && (targetingField != null))
                {
                    // make sure the field can be deleted!
                    targetingField.AllowDeletion = true;
                    targetingField.Sealed = false;
                    targetingField.Update();
                    list.Fields.Delete(targetingField.InternalName);
                    list.Update();
                } 
        }
You can see the highlighted section that I added to Garys code.
 
Cheers!
 
Martin