Showing posts with label WSS. Show all posts
Showing posts with label WSS. Show all posts

Sunday, September 14, 2008

Building a Simple Hello World SharePoint Web Parts with F#

I'm working through the examples in the book Inside Microsoft Windows SharePoint Services 3.0 by Ted Pattison and Daniel Larson and wanted to build a simple hello world web part in F# before attempting the more complicated RssViewWebPart as explained in the book. I start by generating the configuration files DemoWebParts.webpart, feature.xml, and elements.xml.


DemoWebParts.webpart file

<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="DemoWebParts.HelloWorldWebPart" />
<importErrorMessage>Cannot import this Web Part.</importErrorMessage>
</metaData>
<data>
<properties>
<!-- standard Web Part properties -->
<property name="ChromeType" type="chrometype">Default</property>
<property name="Title" type="string">Demo Hello World Web Part</property>
<property name="Description" type="string">Simple example to demonstrate F# in SharePoint</property>
<property name="CatalogIconImageUrl" type="string">
/_layouts/images/msxmll.gif
</property>
<property name="AllowConnect" type="bool">True</property>
<property name="ExportMode" type="exportmode">All</property>

<!-- custom Web Part properties -->
<property name="XmlUrl" type="string">
http://blogs.msdn.com/MainFeed.aspx?Type=AllBlogs
</property>
</properties>
</data>
</webPart>
</webParts>

feature.xml file

<Feature
Id="973F298A-96D3-4d7c-B07A-56925FA13CFF"
Title="Demo Webpart using F#"
Description="Demo webpart using F# based on Chapter 4 of Inside Windows SharePoint Services (Pattison/Larson)"
Hidden="FALSE"
Scope="Site"
ImageUrl="actionssettings.gif"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="elements.xml"/>
</ElementManifests>
</Feature>

elements.xml file

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="DemoWebParts" Path="dwp"
List="113" Url="_catalogs/wp" RootWebOnly="true">

<File Url="HelloWebPart.webpart" Type="GhostableInLibrary" >
<Property Name="Group" Value="F# Demo Web Parts"
</File
</Module>
</Elements>

The F# source file DemoWebParts.fs contains just a single class HelloWorldWebPart that inherits from WebPart.


DemoWebParts.fs


#light

namespace DemoWebParts

open System.Web.UI
open System.Web.UI.WebControls.WebParts

type HelloWorldWebPart() =
class
inherit WebPart()

override this.CreateChildControls () =
base.CreateChildControls()
new LiteralControl("Hello, world!") |> this.Controls.Add

end

[<Assembly: System.Reflection.AssemblyVersion("1.0.0.0")>]
[<Assembly: System.Security.AllowPartiallyTrustedCallersAttribute>]
do()

I need to strong name the created assembly. The following are the command line parameters I used to generate the dll file.

sn.exe -k DemoWebParts.snk

fsc -a --keyfile DemoWebParts.snk -I "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI" -r "Microsoft.SharePoint.dll" DemoWebPart.fs

I then copy all the files to the bin folder of the SharePoint website.

I then need to configure the web.config of the SharePoint site to add a new entry to the SafeControls node in the web.config in order to register the assembly and namespace as safe.


<SafeControl Assembly="DemoWebParts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b89a761d055b9ae3" Namespace="DemoWebParts" TypeName="*" Safe="True" />

The assembly value can be easily pulled by using Lutz Roeder's .NET Reflector tool, which apparently has been acquired by Redgate.

After you copied the dll file along with the configuration files, you then want to navigate to the New Web Part Gallery page which is located at http:///_layouts/NewDwp.aspx.

Select the new web part and click on Populate Gallery Button.

Voila...a F# webpart working in SharePoint!

Tuesday, September 09, 2008

Exploring SharePoint 2007 Object Model with F#

I have been busy with other things that detracted from continued efforts in working with F# and WPF. While I've been busy, I found out that F# 1.9.6 has been released. After quick perusal of F# 1.9.6 release notes, I realized my previously posted codes will break during compilation. Two immediate items that I noticed are:

  • IEnumerable.* are deleted
  • base is now a keyword

I haven't had time to scour my previously posted F# code and correct it to work with F# 1.9.6 so be forewarned if you're trying to compile my previously posted F# code with the new F# compiler. Hopefully, sometime in the future I'll be able to correct the posted code so it compiles and runs with the new F# compiler.

Lately, I have been exploring other pieces of Microsoft technologies such SharePoint 2007, InfoPath 2007, Windows Workflow Foundation, and Excel Services with the goal of crafting a strategy on how to best leverage these technologies in a corporate environment. I needed a way to get up to speed quickly in the SharePoint environment and wanted a way to interactively explore the Windows SharePoint Services (WSS) object model.

I immediately thought of using F# interactive as way to explore WSS object model. I fired up the new F# 1.9.6 interactive shell and wanted to follow the example codes in the book Inside Microsoft Windows SharePoint Services 3.0 by Ted Pattison and Daniel Larson.

Before I could try out the examples in the aforementioned book, I had to created a MOSS 2007 system in a Virtual PC environment based on the instructions by Tony Zink in his post How to Create a MOSS 2007 VPC Image: The Whole 9 Yards .

One problem that I ran into while trying out the examples from the book is that I'm unable to iterate through SPListCollection. SPListCollection does not implement IEnumerable and I do not know an equivalent foreach capability in F#. As a workaround, I implemented the SPListCollectionAdapter as described by Asfar Sadewa in his blog entry linq-ing splistcollection. After implementing this adapter, I can now iterate through SPListCollection as shown in the following example:


Exploring WSS Object Model with F#

#light
#I @"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI"
#r @"Microsoft.SharePoint.dll"
#r @"c:\dev\F#\SharePoint\SharePointUtility.dll"

open Microsoft.SharePoint
open SharePoint.Utility

let path="http://localhost/"
let collection = new SPSite(path)
let site = collection.RootWeb
let lists = SPListCollectionAdapter(site.Lists)
Seq.iter (fun (x:SPList) -> printf "%s\n" x.Title) lists

I was highly encouraged by this initial success. I next tried to implement a simple hello world SharePoint feature as shown in the following code:


Building Test Hello World Sharepoint Feature

#light
namespace HelloWorld

open System
open Microsoft.SharePoint

// From Chapter 1 of Inside Microsoft Windows SharePoint Services 3.0 by Ted Pattison & Daniel Larson
type FeatureReceiver() =
class
inherit SPFeatureReceiver()


override this.FeatureInstalled _ = ()
override this.FeatureUninstalling _ = ()

override this.FeatureActivated (properties:SPFeatureReceiverProperties) =
let site = properties.Feature.Parent :?> SPWeb
site.Properties.["OriginalTitle"] <- site.Title
site.Properties.Update()
site.Title <- "Hello World"
site.Update()

override this.FeatureDeactivating (properties:SPFeatureReceiverProperties) =
let site = properties.Feature.Parent :?> SPWeb
site.Title <- site.Properties.["OriginalTitle"]
site.Update()
end

I was delighted that this worked flawlessly in SharePoint 2007. It looks like I can go back to using some F# in exploring SharePoint 2007.