Monthly Archives: November 2009

SPUtility.DateParse !♥ seconds: SPUtility.DateParse removes the time component if you parse a date that incudes seconds!??!

Okay here’s another baffling API bug:

If you parse a date using SPUtility.ParseDate(web, “11/29/2009 13:37:12”, SPDateFormat.DateTime, false) it will return you a date object without parsing the time!

Remove the seconds SPUtility.ParseDate(web, “11/29/2009 13:37”, SPDateFormat.DateTime, false) and we are good to go. Full program listing of bug follows:

using System;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

public class SPUtilityParseDateTest
{
	public static void RunSnippet()
	{
		using (SPSite site = new SPSite("http://localhost"))
		{
			SPWeb web = site.RootWeb;			
			DateTime parsedDate = SPUtility.ParseDate(web, "11/29/2009 3:37:12 AM", SPDateFormat.DateTime, false);				
			WL(parsedDate.ToString());
				
			parsedDate = SPUtility.ParseDate(web, "11/29/2009 3:37 AM", SPDateFormat.DateTime, false);				
			WL(parsedDate.ToString());
			
		}
	}
		
	#region Helper methods
	
	public static void Main()
	{
		try
		{
			RunSnippet();
		}
		catch (Exception e)
		{
			string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToString());
			Console.WriteLine(error);
		}
		finally
		{
			Console.Write("Press any key to continue...");
			Console.ReadKey();
		}
	}

	private static void WL(object text, params object[] args)
	{
		Console.WriteLine(text.ToString(), args);	
	}
	
	private static void RL()
	{
		Console.ReadLine();	
	}
	
	private static void Break() 
	{
		System.Diagnostics.Debugger.Break();
	}

	#endregion
}

The above code assumes you have US regional settings on your root web.

Tagged , , ,

SPLimitedWebPartManager.SaveChanges throws Microsoft.SharePoint.WebPartPages.WebPartPageUserException: The file is not checked out.

Got stuck on this one for a long time, more than an hour

Microsoft.SharePoint.WebPartPages.WebPartPageUserException: The file is not checked out.  You must first check out this document before making changes.   at Microsoft.SharePoint.WebPartPages.SPWebPartManager.SaveChangesCore(SPLayoutProperties layoutProperties, Boolean httpGet, Boolean saveCompressed, Boolean skipRightsCheck, Guid& newTypeId, Byte[]& newAllUsersProperties, Byte[]& newPerUserProperties, String[]& newLinks)   at Microsoft.SharePoint.WebPartPages.SPWebPartManager.SaveChangesCore(SPLayoutProperties layoutProperties, Boolean httpGet, Boolean saveCompressed, Boolean skipRightsCheck)   at Microsoft.SharePoint.WebPartPages.SPWebPartManager.SaveChangesInternal(SPLayoutProperties layoutProperties, Boolean skipRightsCheck)   at Microsoft.SharePoint.WebPartPages.SPWebPartManager.SaveChanges(Guid storageKey)   at Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager.SaveChanges(WebPart webPart)

I was using the following code to update a webpart

gWeb publishingWeb = PublishingWeb.GetPublishingWeb(webSite);
SPListItem item = publishingWeb.PagesList.GetItemByFileName(pageName);
if (item != null)
{
	SPLimitedWebPartManager webPartManager = item.File.GetLimitedWebPartManager(PersonalizationScope.Shared);
	PublishingPage publishingPage = PublishingPage.GetPublishingPage(item);

	try
	{
		if (item.File.CheckOutStatus == SPFile.SPCheckOutStatus.None)
		{
			publishingPage.CheckOut();						
		}					
		else
		{
			item.File.UndoCheckOut();
			publishingPage.CheckOut();
		}

		WebPart webpart = webPartManger.WebParts[0];
		// Do something with the webpart
		webPartManger.SaveChanges(webpart); // Now the exception is thrown
		
		
		publishingPage.Update();
		publishingPage.CheckIn(updateComment);

		if (publishingWeb.PagesList.EnableModeration)
		{
			item.File.Publish(updateComment);
			item.File.Approve(updateComment);
		}
	}
	finally
	{
		if (webPartManager != null)
		{
			webPartManager.Dispose();
		}
	}
}

A quick google reveals quite a lot of other people stumped with this problem. Why is it saying the file is not checked out, the lines above it make sure it’s always checked out to the user running the code. Turns out it’s quite a simple fix. Don’t instantiate the SPLimitedWebPartManager until your done making sure the page is checked out!

Working code

gWeb publishingWeb = PublishingWeb.GetPublishingWeb(webSite);
SPListItem item = publishingWeb.PagesList.GetItemByFileName(pageName);
if (item != null)
{
	SPLimitedWebPartManager webPartManager = null;
	PublishingPage publishingPage = PublishingPage.GetPublishingPage(item);

	try
	{
		if (item.File.CheckOutStatus == SPFile.SPCheckOutStatus.None)
		{
			publishingPage.CheckOut();						
		}					
		else
		{
			item.File.UndoCheckOut();
			publishingPage.CheckOut();
		}

		// Now we're certain the page is checked out, grab the web part manager.
		webPartManger = item.File.GetLimitedWebPartManager(PersonalizationScope.Shared);

		WebPart webpart = webPartManger.WebParts[0];
		// Do something with the webpart
		webPartManger.SaveChanges(webpart); // Now the exception is thrown
		
		
		publishingPage.Update();
		publishingPage.CheckIn(updateComment);

		if (publishingWeb.PagesList.EnableModeration)
		{
			item.File.Publish(updateComment);
			item.File.Approve(updateComment);
		}
	}
	finally
	{
		if (webPartManager != null)
		{
			webPartManager.Dispose();
		}
	}
}

Notice that we assign the value of the web part manager after we make sure the page is checked out. Hopefully this saves someone a couple of missing hours i’ll never get back 🙂

Tagged , , ,

Provisioning a Web Part with a predefined ID in your onet.xml of element manifest.

From time to time you might want to provision your WebParts using the CAML markup and then modify them in a feature later on. Most examples on the web find the webpart based on it’s title. i.e.

foreach(Webpart webpart in webpartManager.WebParts)
{
   if(webpart.Title == "Title I'm expecting")
   {
       // Do something with the webpart
       webpart.AuthorizationFilter = "";
       webpartManager.SaveChanges(webpart);
   }
}

However you can specify the ID of a web part in your onet.xml / element manifest like so:

 <View List="Lists/MyList" BaseViewID="1" DisplayName="Counter Parties" Name="List Nmae" RecurrenceRowset="TRUE" WebPartZoneID="Header" WebPartOrder="1">
        <![CDATA[
               <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
                    <Assembly>Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
                    <TypeName>Microsoft.SharePoint.WebPartPages.ListViewWebPart</TypeName>
                    <Title>MyList - Workflow Users</Title>
                    <DetailLink>~Site/Lists/MyList/AllItems.aspx</DetailLink>
                    <Description>Use this list to store ... information.</Description>
                    <ID>g_45C819FD_FC4C_44e1_81DD_3AE4FCC34D37</ID>
               </WebPart>
            ]]>
      </View>

Create a new Guid replace the hyphens with underscores and add a “g_” to the beginning of the string g_45C819FD_FC4C_44e1_81DD_3AE4FCC34D37.

Now we can reference the web part in your feature receiver using the indexer property, which is I think you’ll agree much more elegant and less error prone:

Webpart = webpartManager["g_45C819FD_FC4C_44e1_81DD_3AE4FCC34D37"]
// Do something with the webpart
webpart.AuthorizationFilter = "";
webpartManager.SaveChanges(webpart);
Tagged , , ,

Problems installing SharePoint 2010 Beta 2 – SQL Server at XXX has an unsupported version 10.0.2531.0. The minimum required SQL versions…..

First little problem I came across when installing SharePoint 2010 was the following error:

SQL Server at XXX has an unsupported version 10.0.2531.0. The minimum required SQL versions are SQL Server 2005 SP3 CU3, version number: 9.00.4220.00, downloadable from “http://support.microsoft.com/kb/967909”, or SQL Server 2008 SP1 CU2, version number 1.00.2714.00, downloadable from “http://support.microsoft.com/kb/970315”.

 

CU stands for cumulative update. I was missing the cumulative update for SQL Server 2008, once that was applied setup would allow me to continue.

Tagged ,

SharePoint can not debug assemblies

If you are ever having problems getting Visual Studio to break into your code and you develop by deploying your dll’s into the GAC, it’s probably down to mismatching PDB’s.

  1. Do a Clean Solution
  2. Rebuild the solution
  3. Re-Gac all your dll’s
  4. Reattach to IIS processes

Other hints

Locked files in the GAC

Some times a process will take a lock on an assembly and if, like me, you use WSPBuilder to re-gac your assemblies, you might not notice that it fails to re-gac them. Crack open process explorer, find the rogue process and “Get Some”. Usually Visual Studio is the culprit here.

Tagged ,

Shared Services Administration: Add Audience Rule – No exact match was found. Error

Trying to setup an audience this morning based on being a “Member Of” an Active Directory group. The Active directory group had been created earlier, however entering it into the value field kept producing the annoying

 

No exact match was found.

Your mileage may vary but I solved this issue by:

  • Running a full import on my user profile
  • Updating the people scopes
  • Running an IISRESET
Tagged , ,

How to add an image web part / ImageWebPart part via your onet.xml or elements manifest

<AllUsersWebPart WebPartZoneID="RightZone" WebPartOrder="4">
  <![CDATA[
      <WebPart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/WebPart/v2">
        <Title>Employee Emergency Line</Title>
        <FrameType>None</FrameType>
        <Description>Use to display pictures and photos.</Description>
        <PartImageSmall />
        <PartImageLarge>/_layouts/images/msimagel.gif</PartImageLarge>
        <Assembly>Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
        <TypeName>Microsoft.SharePoint.WebPartPages.ImageWebPart</TypeName>
        <ImageLink xmlns="http://schemas.microsoft.com/WebPart/v2/Image">/SiteCollectionImages/logo.gif</ImageLink>
        <AlternativeText xmlns="http://schemas.microsoft.com/WebPart/v2/Image" />
        <VerticalAlignment xmlns="http://schemas.microsoft.com/WebPart/v2/Image">Middle</VerticalAlignment>
        <HorizontalAlignment xmlns="http://schemas.microsoft.com/WebPart/v2/Image">Center</HorizontalAlignment>
        <BackgroundColor xmlns="http://schemas.microsoft.com/WebPart/v2/Image">transparent</BackgroundColor>
      </WebPart>
   ]]>
</AllUsersWebPart>

Properties of note:

  • ImageLink
    Url to image, can be relative. Note tokens are supported in this xml element, i.e. ~SiteCollections/SiteCollectionImages/logo.gif
Tagged , , ,

How to add a content editor web / ContentEditorWebPart part via your onet.xml or elements manifest

 
<AllUsersWebPart WebPartZoneID="TopZone" WebPartOrder="2">
![CDATA[                     
	<WebPart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/WebPart/v2">
        <Title>Web part title</Title>
        <FrameType>None</FrameType>
        <Description>Web part description</Description>
        <FrameState>Normal</FrameState>
        <Assembly>Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
        <TypeName>Microsoft.SharePoint.WebPartPages.ContentEditorWebPart</TypeName>
        <ContentLink xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
        <Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor">
         &lt;div class=&quot;ms-sblink&quot;&gt;
           &lt;a href=&quot;javascript:HelpWindowKey('how_content_is_searched')&quot;&gt;
             $Resources:spscore,PrivacyStatementWP_LinkText;
           &lt;/a&gt;
        &lt;/div&gt;
        </Content>
        <PartStorage xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
		</WebPart>             
  ]]> 
</AllUsersWebPart>

The important part here is to remember to html encode the Content element. You can encode html online using this handy website: http://www.opinionatedgeek.com/dotnet/tools/htmlencode/Encode.aspx

Tagged , , ,

How to add a list view web part to onet.xml or your elements manifest

     

 <View List="Lists/Registrations" BaseViewID="3" DisplayName="Pending Registrations" Name="Pending Registrations" RecurrenceRowset="TRUE" WebPartZoneID="Left" WebPartOrder="1">
  <![CDATA[
             <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
                  <Assembly>Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
                  <TypeName>Microsoft.SharePoint.WebPartPages.ListViewWebPart</TypeName>
                  <Title>Pending Registrations</Title>
             </WebPart>
      ]]>
</View>

BaseViewID: Optional Integer. Specifies the ID of the base view. BaseViewID has a corresponding property on SPView

For more information hit up MSDN: http://msdn.microsoft.com/en-us/library/ms441170.aspx

Tagged , , , ,

Restoring an old friend – Visual Studio 2008 Create GUID tool

Remember to recreate a link to guidgen.exe (Guid generator tool) after installing Visual Studio 2008. For some reason it’s no longer out of the box?

 

  1. Choose the Tools -> External Tools...
  2. Title: Create &GUID
  3. Click the Browse (…) button and find the guidgen.exe in the C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\ folder.

See a better crafted posting with pretty pictures and idiot proof step-by-step guide@ http://karinebosch.wordpress.com/2009/05/28/create-guid-in-visual-studio-2008/

Tagged ,