zevenseas

Our News

Expanding our operations in other countries more


 

Re-using SharePoint controls

This post is going to be a summary of some of some the SharePoint controls I regularly use in my solutions. Cool thing about re-using the controls that are already out there is, that saves time in re-inventing the wheel and you don’t have to worry about keeping the look&feel consistent ;)

First, check out the following blog posts for more information on re-using the out-of-the-box controls of SharePoint

 

Now some controls are already covered by the links that are stated above, so this is really just a quick summary on the things I like to use most ;)

I’ve given each control a table, in the first row there is a screenshot (if applicable) how to control looks like when it’s rendered by SharePoint,
in the second row there is the declarative way of using the control,
in the third row there is (also, if applicable) some codebehind logic on how to  use the control and it’s value.

WebApplicationSelector 

webapplicationselector
<SharePoint:WebApplicationSelector ID="webApplicationSelector" runat="server" />
protected WebApplicationSelector webApplicationSelector;
..
SPWebApplication webApplication = webApplicationSelector.CurrentItem;

 

SiteAdministrationSelector

siteadministrationSelector
<SharePoint:SiteAdministrationSelector runat=server ID="siteadminselector" /> 
protected SiteAdministrationSelector siteAdministrationSelector;
..
SPSiteAdministration siteAdmin = siteAdministrationSelector.CurrentItem;

 

SchedulePicker , for more info on this one and when & why you should use this please read “Using the SchedulePicker” ;)

schedulepicker (2)

<%@ Register TagPrefix="wssuc" TagName="SchedulePicker"

src="~/_controltemplates/SchedulePicker.ascx" %>

<wssuc:SchedulePicker id="schedulePicker"Hourly="True"

Weekly="True" Monthly="True" Enabled="True" EnableStateView="True" runat="server"/>

protected SchedulePicker schedulePicker;
..
//Getting a schedule from the picker
SPSchedule schedule = schedulePicker.Schedule;
//Setting the schedule of the picker
schedulePicker.ScheduleString = schedule.ToString();

 

SPDatePickerControl 

spDatePickerControl
<script type="text/javascript" 
src="/_layouts/datepicker.js"></script>
<SharePoint:SPDatePickerControl id="datePickerControl" 
   runat="server"/>

 

ButtonSection

buttonsection
<%@ Register TagPrefix="wssuc" TagName="ButtonSection" 
src="~/_controltemplates/ButtonSection.ascx" %>
<wssuc:ButtonSection runat="server">
    <Template_Buttons>
        <asp:Button runat="server" class="ms-ButtonHeightWidth" 
        OnClick="OnClickOK" Text="<%$Resources:wss,multipages_okbutton_text%>" 
        id="btnOk" accesskey="<%$Resources:wss,okbutton_accesskey%>"/>
    </Template_Buttons>
</wssuc:ButtonSection> 
When making use of the LayoutsPageBase in your codebehind, you can define the URL of the Cancel button by using this snippet:
public override string PageToRedirectOnCancel
{
    get
    {
        //return base.PageToRedirectOnCancel;
        return "/_layouts/settings.aspx";
    }
}

 

InputFormSection & InputFormControl

inputformsectionandcontrol
<%@ Register TagPrefix="wssuc" 
TagName="InputFormSection" 
src="~/_controltemplates/InputFormSection.ascx" %>
<%@ Register TagPrefix="wssuc" 
TagName="InputFormControl" 
src="~/_controltemplates/InputFormControl.ascx" %>
<wssuc:InputFormSection Title="InputFormSection"
    Description="InputFormSection Description" runat="server">		
    <template_inputformcontrols>            
        <wssuc:InputFormControl runat="server" LabelText="InputFormControl Text">
            <Template_Control>
                <%--Put a control here--%>
                </Template_Control>
        </wssuc:InputFormControl> 
    </template_inputformcontrols> 
</wssuc:InputFormSection> 

 

InputFormTextBox, notice there are two InputFormTextBoxes shown here. One with the RichTexT property set to true and the other set to false. So with a simple property change you can get the nicely and shiny FullHTML textbox.

inputformtextbox1

<SharePoint:InputFormTextBox ID="ApproveMailSubject" RichText="false"

runat="server" Width="100%"/>

<SharePoint:InputFormTextBox ID="ApproveMailContent" RichText="true" 
	RichTextMode="FullHtml" 
	runat="server" 
	TextMode="MultiLine" 
Rows="20"/>

 

InputFormRequiredFieldValidator

inputformrequiredvalidator
<wssawc:InputFormTextBox ID="uxFirstName" RichText="false" 
    TextMode="Singleline" runat="server" Width="100%"/>	
<wssawc:InputFormRequiredFieldValidator ID="uxFirstNameValidator"
    ControlToValidate="uxFirstName" Text="Error" runat="server"
    ErrorMessage ="First name is required" 
    EnableClientScript="true" Display="Dynamic">
</wssawc:InputFormRequiredFieldValidator>
 

InputFormRangeValidator

inputformrangevalidator
<wssawc:InputFormRangeValidator 
    ID="inputFormRangeVal" 
    Type="Integer" MinimumValue="1" MaximumValue="30"
    ControlToValidate="uxNumberOfDays"
    ErrorMessage="Value must between 1 and 30" 
    Runat="server" />

 

ToolBar & ToolBarButton

toolbar
<%@ Register TagPrefix="wssuc" TagName="ToolBar" 
src="~/_controltemplates/ToolBar.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ToolBarButton" 
src="~/_controltemplates/ToolBarButton.ascx" %>
<wssuc:ToolBar id="Toolbar" runat="server">
	<template_buttons>
		<wssuc:ToolBarButton runat="server"
			id="ViewSites"
			Text="View Sites"
			ToolTip=""
			OnClick="ViewSites_Link"
			ImageUrl="/_layouts/images/newitem.gif"
			Padding="2px"
			AccessKey="V" />			
	</template_buttons>
	<template_rightbuttons>

<SharePoint:WebApplicationSelector id="Selector"

runat="server"/>

	</template_rightbuttons>
</wssuc:ToolBar>
To use the ToolBar in your WebPart you can load the UserControls and reference them using this:

protected ToolBarButton ToolBarButton;
protected ToolBar ToolBar;
..
//Adding a ToolBarButton
ToolBarButton = 
    (ToolBarButton)Page.LoadControl("/_controltemplates/ToolBarButton.ascx");
ToolBarButton.Click += new EventHandler(ToolBarButton_Click);
ToolBarButton.Text = "Complete selected tasks";
ToolBarButton.ImageUrl = "/_layouts/images/CheckNames.gif";
//Adding the ToolBar
ToolBar = 
    (ToolBar)Page.LoadControl("/_controltemplates/ToolBar.ascx");
ToolBar.Buttons.Controls.Add(ToolBarButton);
this.Controls.Add(ToolBar);

Why are PortalSiteMapProvider properties defined in the web.config?

FYI, this post is a rant on a MOSS specific component called PortalSiteMapProvider.. ;)

I was asked by a the customer where I’m currently working for if it was possible to display more than 50 items on a fly-out in the global navigation. Being the SharePoint guru that I am, I started googling on how to adjust this.. Quickly I found the DynamicChildLimit property on the PortalSiteMapProvider class in the Microsoft.SharePoint.Publishing.Navigation namespace!

But then I quickly found out that I needed to modify the web.config to set this property?! WHY?!?!

Why did the team decide to put this type of parameters in the web.config? Why not create an application page in the Central Administration where you can view and set all those parameters..  I mean.. it’s not just one parameter like the DynamicChildLimit in the web.config. But, out of the box, there are several properties defined which you can set like:

  • NavigationType
  • EncodeOutput
  • IncludePages
  • IncludeHeadings
  • IncludeAuthoredLinks

I can understand that you need to register all the SiteMap providers in the web.config, but I don’t understand why the properties of the providers are set in the web.config. I know it’s a ASP.NET component, but since it’s part of the Microsoft.SharePoint.Publishing.Navigation namespace and they override initialization method I would have figured they would get the parameters from somewhere else..

  if (config["DynamicChildLimit"] != null)
    {
        this.DynamicChildLimit = int.Parse(config["DynamicChildLimit"]);
    }


If someone knows why it’s implemented like this.. please let me know because I would love to know it! :)

 

Technorati Tags: ,

Speaking at the SDN Event on 26th of June

Together with SharePoint legends Box Fox and Spence Harbar, I have the privilege to also host a session at the Software Development Network in Houten (the Netherlands) on the 26th of June! While Bob and Spence are covering the following topics

I will be talking about SharePoint Application Pages..

When you are developing custom solutions on top of SharePoint you often need a page (or maybe even more) in Central Admin where you can configure your solution. And of course you want to this page to look like a SharePoint page and probably you also want to use the SharePoint controls because, if you are like me, you are a lazy developer and don’t want to reinvent the wheel over and over gain. Aside to settings the configuration you are also interested in how to store your configuration.

My session will be about creating those fancy application pages and can be summarized into the following bullets :

  • What is an Application Page?
  • What SharePoint controls are there for me to re-use?
  • How do I store my configuration?
  • The things I’ve learned with custom timer jobs

For more information, check out the SDN site and register! ;)

New MOSS SP2 bug?

I twittered about this problem two weeks ago I merely thought that it’s possibly my own fault because of the development work I was doing.. So recreated my environment by reinstalling SharePoint and everything was fine (though it’s quite irritating that when you attach your ‘old’ contentdatabases to your new farm it starts indexing everything from scratch and the mssearch/msddmn and sqlserver starts consuming all resources.. and that’t not funny on a VPC ;) but after a clean SharePoint (with SP2) install everything was fine again..’Till now!  I got the same error back again.

First it starts with this when navigating to a SharePoint site in my browser..

[SPUpgradeException: An error has occurred on the server.http://go.microsoft.com/fwlink?LinkID=96177]
   Microsoft.SharePoint.Administration.SPContentDatabase.ValidateDatabaseSchemaCompatibility() +1805
   Microsoft.SharePoint.SPSite.PreinitializeServer(SPRequest request) +61
   Microsoft.SharePoint.SPWeb.InitializeSPRequest() +290
   Microsoft.SharePoint.SPWeb.EnsureSPRequest() +58
   Microsoft.SharePoint.SPWeb.get_Request() +54
   Microsoft.SharePoint.SPWeb.GetWebPartPageContent(Uri pageUrl, PageView requestedView, HttpContext context, Boolean forRender, Boolean includeHidden, Boolean mainFileRequest, Boolean fetchDependencyInformation, Boolean& ghostedPage, Byte& verGhostedPage, String& siteRoot, Guid& siteId, Int64& bytes, Guid& docId, UInt32& docVersion, String& timeLastModified, Byte& level, Object& buildDependencySetData, UInt32& dependencyCount, Object& buildDependencies, SPWebPartCollectionInitialState& initialState, Object& oMultipleMeetingDoclibRootFolders, String& redirectUrl, Boolean& ObjectIsList, Guid& listId) +1492
   Microsoft.SharePoint.ApplicationRuntime.SPRequestModuleData.FetchWebPartPageInformationForInit(HttpContext context, SPWeb spweb, Boolean mainFileRequest, String path, Boolean impersonate, Boolean& fGhostedPage, Byte& verGhostedPage, Guid& docId, UInt32& docVersion, String& timeLastModified, SPFileLevel& spLevel, String& masterPageUrl, String& customMasterPageUrl, String& webUrl, String& siteUrl, Guid& siteId, Object& buildDependencySetData, SPWebPartCollectionInitialState& initialState, String& siteRoot, String& redirectUrl, Object& oMultipleMeetingDoclibRootFolders, Boolean& objectIsList, Guid& listId, Int64& bytes) +718
   Microsoft.SharePoint.ApplicationRuntime.SPRequestModuleData.GetFileForRequest(HttpContext context, SPWeb web, Boolean exclusion, String virtualPath) +232
   Microsoft.SharePoint.ApplicationRuntime.SPRequestModule.InitContextWeb(HttpContext context, SPWeb web) +104
   Microsoft.SharePoint.WebControls.SPControl.SPWebEnsureSPControl(HttpContext context) +395
   Microsoft.SharePoint.WebControls.SPControl.GetContextWeb(HttpContext context) +31
   Microsoft.SharePoint.ApplicationRuntime.SPRequestModule.PostResolveRequestCacheHandler(Object oSender, EventArgs ea) +383
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +68
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

And the EventViewer showed this error:

The schema version (3.1.8.0) of the database SharePoint_AdminContent_3b1b1115-48b5-40d1-afe3-142692142cd6 
on dev is not consistent with the expected database schema version (3.1.3.0) on dev.  
Connections to this database from this server have been blocked to avoid data loss.  
Upgrade the web front end or the content database to ensure that these versions match.
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

Looks quite scary since the SharePoint_AdminContent database is the contentdatabase of the Central Administration WebApplication. But it makes sense for me, since I’m using this Web Application extensively in my solutions. On the other hand I find it quite strange because it’s not the first time that I’m doing this and did not do anything that obscure or scary.

So of course, I tried to do an upgrade using the STSADM –o upgrade –url <centraladmin> –inplace.. When I checked in the Upgrade.log I found this error

[SPDelegateManager] [DEBUG] [5/29/2009 11:54:04 AM]: No assembly manifest found.
[SPDelegateManager] [ERROR] [5/29/2009 11:54:04 AM]: Failed to call GetTypes()
[SPDelegateManager] [ERROR] [5/29/2009 11:54:04 AM]: Could not load type 'Microsoft.Office.Server.Administration.Health.SPHealthAnalysisRule' from assembly 'Microsoft.Office.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'.
[SPDelegateManager] [ERROR] [5/29/2009 11:54:04 AM]: Failed to call GetTypes()
[SPDelegateManager] [ERROR] [5/29/2009 11:54:04 AM]: Could not load type 'Microsoft.Office.Server.Administration.Health.SPHealthAnalysisRule' from assembly 'Microsoft.Office.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'.
[SPManager] [ERROR] [5/29/2009 11:54:04 AM]: CanUpgrade [SPFarm Name=SharePoint_Config] failed.

Now if I’m not mistaken, the Health class is added to the Microsoft.Office.Administration namespace since SP2 right?

Next thing was to try do an upgrade using the PSConfig tool.. and I got an Access Denied error

An exception of type System.Security.SecurityException was thrown.  Additional exception information: Access denied.
System.Security.SecurityException: Access denied.
   at Microsoft.SharePoint.Administration.SPPersistedObject.Update()
   at Microsoft.SharePoint.Administration.SPService.Update()
   at Microsoft.SharePoint.Administration.SPPersistedObject.Update(Boolean ensure)
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.InstallServiceInConfigDB(Boolean provisionTheServiceToo, String serviceRegistryKeyName)
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.InstallServices(Boolean provisionTheServicesToo)
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.Run()
   at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()
The Zone of the assembly that failed was:
MyComputer

So I think the error about the “Could not load type..” and the SecurityException are linked to each other.

I tried the ‘execadmsvcjobs’ command to see if that give me any errors.. it didn’t..  but the ‘sync’ command did throw an error and in the ULS it showed this :

05/29/2009 13:47:02.21 	STSADM.EXE (0x17E0)
0x0C44	1597  6y3d	Exception	 
System.Security.SecurityException: Access denied.     
at Microsoft.SharePoint.Administration.SPPersistedObject.Update()     
at Microsoft.SharePoint.Administration.SPJobDefinition.Update()     
at Microsoft.Office.Server.CommandLine.SyncCommands.ProcessScheduleParams(
String multipleWebAppUrls, SPSchedule sweepSchedule, SPSchedule syncSchedule)     
at Microsoft.Office.Server.CommandLine.SyncCommands.Execute()  
The Zone of the assembly that failed was:  MyComputer

Some background information on what I was doing when this happened,  I was working on a custom timer job and restarted the Timer service a lot of times.. And ‘suddenly' the environment was down. When it happened a couple of weeks ago I did a solution install and during an installation of a solution package the Timer Service is also restarted. And when a Timer service restarts, a lot of timer jobs are also being executed right? Maybe the upgrade timer job was still busy trying to update the content database of my Central Administration but never got the chance or something..

<Update>

Found some blogposts that describe the problem after applying a hotfix and servicepacks

 

Only ‘weird’ thing is that this didn’t happen to me after a the service pack update but after two weeks after applying the service pack. So I’m still convinced it’s a timer job issue..

</Update>

 

Up to this point I don’t have a solution for this problem, but if I do I will update this post.. or if you have the solution.. let me know! ;)

TunnelPoint and ProduShare

I don’t know if you have been following the posts from Hans and Daniel about TunnelPoint and (the assembly free solution store called) ProduShare but I wanted to express my feelings about the products we have launched.. Though I was a bit skeptical at first  when we started months ago.. but now as both products have launched I’m really proud and have much believe that the product will be a succes :)

Why? Well.. well hopefully because we are the first ones who took the path of (the more popular getting) talking to SharePoint without using the Object Model and taking the next step..

Just to show you that the clientside ‘development’ is getting more popular, check out these posts:

I bet you are probably asking yourself “so what do TunnelPoint and ProduShare” have to do with this? Well.. let me tell you..

TunnelPoint, this is basically “the BDC in the cloud” (copyright by Daniel). What it does it connects a SharePoint list with a webservice that is available in the cloud, so it’s actually a broker between SharePoint and the cloud. So instead of a webpart that is showing stockqoutes in your site, we push stockqoutes in your SharePoint list. Meaning that it is SharePoint data.. and you know what that means.. it means that you can act on it and use it using out-of-the-box SharePoint functionality like alerts, workflow, views with totals, max, sum’s that creates a much more richer experience than a simple webpart does that shows data that is and stays external.. Imagine that with the availability of hundreds of webservices/api’s that provide some sort of value that you want to have in SharePoint.

ProduShare, we all know the fantastic 40 templates right? We all know custom themes right and masterpages right? What is the downside of these things right now? They require server access to be installed (well maybe not the masterpages (but that’s detail ;)).. so what if you have a SharePoint environment where you cannot touch your server, like SharePoint online for example. Or you are a power-user and your IT department won’t let you use SharePoint Designer to customize your site. Well now, if your SharePoint environment is accessible via the internet, you can customize with a single click using ProduShare! ;) Just think of it as the Appstore for the IPhone but then for SharePoint..

Please note, this post probably sounds very commercial but it’s really not my intention.. though of course I’m very biased about this whole thing since it’s our own product ;)

If you are interested in what some folks of the community thought about TunnelPoint check out the following posts :

And if you want to be informed with all the things that are currently going on with these products or you want to try it out and give us feedback, tune into Hans’s blog! :)

 

UpdateListItems vs ProcessBatchData to create Folders

Currently I’m busy in creating huge amounts of folders and I want to have the best performance doing so. So.. I know about the ProcessBatchData method on the SPWeb object that is designed to do ‘batch’ stuff in a very optimized way. Only problem was that I never created folders by using this method.

I thought “hey.. a folder is just a list item with it’s content type set to Folder right?” So by defining the ContentType, the folders were created!! Yeah!! But… SharePoint now was treating this ListItem as a File so it uses the “Name” column instead of the “Title” column to display the Title. So every folder looked like this :

folders_notitle[1]

To fix this I tried the adding following fields :

  • BaseName, generating error “Bad parameter passed to Web Server Extensions.  Check the information you entered and try again”
  • Name, generating error “One or more field types are not installed properly. Go to the list settings page to delete these fields”

in combination with the “urn:schemas-microsoft-com:office:office” schema and without but all the same result.

Here is the xml snippet which I use if you are interested ;)

string methodFormat = "<Method ID=\"{0}\">" +
"<SetList>{1}</SetList>" +
"<SetVar Name=\"ID\">New</SetVar>" +
"<SetVar Name=\"Cmd\">Save</SetVar>" +
"<SetVar Name=\"urn:schemas-microsoft-com:office:office#Title\">{2}</SetVar>" +                
"<SetVar Name=\"urn:schemas-microsoft-com:office:office#ContentType\">Folder</SetVar>" +
"</Method>";

I found the Save Method (RPC) page on MSDN which explains a lot of this mysterious CAML and tried a lot of different things but didn’t get any further. Maybe that was a good thing as well since it states that “This method is deprecated and may not be supported in future releases. Instead, use the following Web service method: UpdateListItems Web service method.” So I went there and to my suprise (and delight) the method also accepts a ‘batch’ string. So by using the following snippet I managed to create all the folders I wanted :

string methodFormatListItem = "<Method ID='{0}' Cmd='New'> " +
"<Field Name='FSObjType'>1</Field>" +
"<Field Name='BaseName'>{1}</Field>" +
"<Field Name='ID'>New</Field></Method>";

Only thing that keeps me worried is ‘ how bad is the performance when using the webservice instead of the ProcessBatchData? ’ By doing a test that creates 100 folders 9 times in a row I came up with the following results table (each number is the time measured in milliseconds) :

ProcessBatchData UpdateListItems
1916 3236
874 963
1058 846
1310 967
682 1042
824 1128
674 1012
721 1424
648 1077


And in a graph it looks like this:

webserviceprocessbatchdata[1]

So actually only the first hit is the most expensive one but after the first one, it becomes quite reasonable in my opinion. Of course the ProcessBatchData is the better performing one but the webservice wasn’t that bad as I thought it would be.

Useful references:

 

Technorati Tags:

zevenseas FeatureBlocker updated

Just to let you know, I’ve updated my FeatureBlocker solution. Now, next to disabling the activate/deactivate button, I’ve added the following ‘features’ :

  • Hide the entire feature (row), this is great if you have an environment that has a lot of features and you want to hide those from your users.
  • Redirect the users to another url once they click on the activate button
  • Exclude farm administrators from having this ‘restrictions’ in place.

Here is a screenie how it looks in the application page in Central Admin ;)

So.. what are you waiting for? Grab it from codeplex here ! ;) And let me know what you think!

 

Technorati Tags:

Why I love twitter

This morning I had some troubles with my VPC.. for some weird reason, some webapplications kept prompting to authenticate while working locally on my VPC. But when accessing them remotely I had no problems at all. And I had the same problem last week, but then a simple reboot did the trick.. it didn’t do the trick this morning so I asked in twitter the following question :

quick #SharePoint question : wondering why all of a sudden certain webapps on my vpc keep asking for credentials.. resulting in 401.1's

And literally within minutes I had this result to solve my problem!! ;)

This truly, for me, makes twitter such a powerful social tool to have! So thanks all!

FYI : if you want to know the solution, go to http://support.microsoft.com/kb/896861 and check method 2. That did the trick for me ;)

Assembly free Twitter-like solution for SharePoint

I’m really impressed with the work that Daniel is being doing lately with all the assembly free stuff.. and now he created a twitter like solution that is completely assembly free! And as Daniel says :

To be clear, this is simply a Site Template. Nothing more, nothing less

You obviously want to know how it looks right? Well here’s a screenshot..

and if you are not really convinced you can try it out here on our demo page and use the following accounts to play with :

Usernames: ZSHOSTED\teamstatus, ZSHOSTED\teamstatus2, ZSHOSTED\teamstatus3
Passwords: (passwords are the same as username, eg. teamstatus, teamstatus2, teamstatus3

Or if you want to download it (since it’s nothing more than a site template) you can grab it here

Let us know what you think of it ! ;)

About custom Timer Jobs and SPJobLockTypes

If you are just starting with creating your own custom timer jobs, you probably run into the posts of AC (Creating Custom SharePoint Timer Jobs , MOSS Timer Jobs - Create Your Own!) and his MSDN article Creating Custom Timer Jobs in Windows SharePoint Services 3.0 and you start using the examples provided and build your very own first timer job right? (I know I did .. and if it wasn’t for his posts and articles in the first place, this post wouldn’t exist ;)

So what is this post about then? Well.. in all the examples provided you will see when defining the timer job the SPJobLockType is set to “ContentDatabase”.

public SharePointWarmupJob (SPWebApplication webApp)
      : base(Globals.JobName, webApp, null, SPJobLockType.ContentDatabase) {
      this.Title = Globals.JobName;

And when referring to the SDK for explanation this is what it says :

- SPJobLockType.ContentDatabase   Locks the content database associated with the job
- SPJobLockType.Job   Locks the job to prevent multiple instances of the job from running on a single server
- SPJobLockType.None   No locking.

There is another post called Where is My Timer Job? by Scot Hillier where he tests what the real difference is between the Job and the None LockTypes and he discovers when setting these timerjobs in a multi server farm that the Job LockType ensures that it only runs on one server. And the None ensures that the job runs on every server.

But Scot doesn’t mention what happens if you use the ContentDatabase LockType.. in short, it’s almost the same as the Job one, meaning that it only runs one server.. BUT..  as Peter find out at Help needed with custom timerjob in SharePoint 2007 , the job runs for each ContentDatabase that the WebApplication is associated with. Another (quite annoying) fact is that it is not that predictable when it will run on the next content database.

This usually is being discovered when the timer job is already in production (it’s pretty safe to assume that most developers don’t have multiple content databases associated with their WebApplications..) and at that time you don’t have a clue why it’s displaying this kind of behavior.

So if you are not doing stuff that is bound to a specific ContentDatabase (like moving or backing up sitecollections (since sitecollections are stored per contentdatabase)) you are most of the time better of using the Job SPLockType.

 

Technorati Tags: ,

 Next >>

 
 
 

© 2009 Community Kit For SharePoint