SharePoint pre-conference at TechDays 2009 - not to miss!

It’s been a long time since I’ve done any posts on this blog, mostly because I’m posting mainly on my MSDN blog and not doing a lot of SharePoint lately.

But, I have a good reason to post this time: I’ve been working on the content, speakers and agenda for the next TechDays conference these last few months.
This year the event takes place on 10, 11 and 12 March in Antwerp, with a different setup than last year: we have a full day pre-conference entirely focused on SharePoint development in .NET Framework 3.5, and two days conference with more than 75 sessions (agenda here)! That’s Developer and IT-Pro sessions combined but even then it’s a lot :)

For the pre-conference there are 5 sessions planned for the day, in which you will learn not only about SharePoint development but in addition how to use the latest technologies from the .NET Framework 3.5 including LINQ, WCF and Silverlight.

  • SharePoint 2007 Architecture and Development Overview
  • Using LINQ with SharePoint
  • Consuming and exposing SharePoint services using WCF
  • Using Workflow Foundation 3.5 with SharePoint 2007
  • Integrating Silverlight 2 into SharePoint

Speakers: two speakers from U2U are presenting during this pre-conference. Jan Tielens: MVP, famous blogger and the author of the SmartPart, and his colleague Lieven Iliano. In addition to making this a not to miss pre-conference content-wise, I’m sure Lieven and Jan will make this a fun day as well.

In addition to the developers pre-conference on SharePoint there are two more: Windows Server 2008 R2 Essentials and Software + Services.

Register in time on www.techdays.be.

See you there!


Podcasting Kit for SharePoint (PKS): a free add-on to MOSS 2007

Interesting release on CodePlex earlier this month: the Podcasting Kit for Sharepoint. This kit allows you to more easily integrate a podcasting solution into SharePoint 2007.

Current release is still pre-beta but they are planning to have a production ready release by Septebmer 2008.
 
Some of the features are:

  • Listen and watch audio/video podcasts, anywhere on your PC or mobile device (Zune, SmartPhone, or any podcasting device)
  • Share content by producing your own audio/video podcasts and publish them on PKS on your own.
  • Tag cloud
  • Comments
  • Rating system
  • Play podcasts in real-time using Microsoft® Silverligh and progressive playback
  • And more…

Definitely worth checking out before you think about creating your own solution from the ground up.

As the PKS uses WMV as a video format, you might also be interested in a side project, “Server Side Re-encoding for Podcasting Kit for SharePoint”, an add-on that converts several video and audio formats to WMV.

 

Technorati tags: , ,

 

 


Visual Studio 2008 extensions for WSS 3.0 v1.2 and other resources

Last week during TechEd Orlando, the new version of the Visual Studio extensions for Windows SharePoint Services 3.0 were announced: it’s now finally here, a version compatible with Visual Studio 2008. This version brings the same functionalities as v1.1 for Visual Studio 2005, among others:

  • Full Debugging with Microsoft Office SharePoint Server
  • Support for C# and VB.NET
  • Templates for Web Part, Team Site, List Definition, Field Control, Content Type, Event Handler and more.
  • Web Solution Package (WSP) Editor
  • Solution Generator creates Site Definition projects from an existing site

Check out my Resources page for the download link.

Now that I’m doing this post, it’s worth mentioning the latest additions to my SharePoint Resources page:

  • SharePoint 2007 Shared Services Provider User Profile Importer
  • SharePoint Content Deployment Wizard - http://www.codeplex.com/SPDeploymentWizard
    This tool by Chris O'Brien helps you export sites, lists, etc using .cmp files (Content Migration Package).
  • WSS3 Workflow Designers
  • SmartPart for SharePoint
    The SharePoint web part which can host any ASP.NET web user control. Create your web parts without writing code! – Now with support for ASP.NET Ajax.
  • STSDEV
    STSDEV is a proof-of-concept utility application which demonstrates how to generate Visual Studio project files and solution files to facilitate the development and deployment of templates and components for the SharePoint 2007 platform.
  • SharePoint SUSHI (that’s a cool name as I love sushi!)
    SUSHI is a powerful, user-friendly SharePoint application enabling you to accomplish common SharePoint administrative and development tasks. You can think of SUSHI as a Swiss army knife for SharePoint.
  • SharePoint SmartTemplates for Visual Studio
    Another project by Jan Tielens, already famous with the creation of the SmartPart (see above).

 

Technorati tags: , , , ,

 


Final release of VSeWSS 1.1 is out

Good news comes to us from the Office Developers Conference: version 1.1 of VSeWSS (Visual Studio Extensions for Windows SharePoint Services) has been released.

Several new features have been added:

  • Solution Package Editing (renaming Features, reordering Features and more)
  • Visual Basic support
  • New item templates (List Instance, List Event Handler)
  • Bug fixes:
    • No more GUIDs in Feature Names
    • Support complex project names, e.g. with periods.
    • Can deploy assemblies to the bin folder, instead of GAC

See the complete list and download the tool over at the SharePoint Team Blog.
Also available now is a user guide to VSeWSS and what's coming with version 1.2.

 

Technorati tags: , ,

 


Two questions for Spencer Harbar

Yesterday I had the chance to ask two quick questions to Spencer during TechEd:

What is your favorite WCM feature in MOSS?
Definitely Content Query Web Part: this is an extremely powerful feature that is largely underestimated. This web part is very efficient both in performance and very easy to customize its look without one line of code (compiled code that is, you still need some XSLT code).

How is your book on WCM together with Andrew Connell going?
It’s coming along very well, a bit slower than we had hoped. The first draft version has just been finished for a first review and people should be able to get it in the beginning of next year.

Thanks Spencer for the time!

 


TechEd Session on performance for Internet facing web sites in SharePoint 2007

I just went to my first session on SharePoint during this edition of TechEd: “Building a High Performance .com Site on Microsoft Office SharePoint Server 2007”.
Spencer Harbar brought us an informative overview of the top things to take into account in regards to performance in WCM SharePoint sites.

Here are some of my notes:

  • Performance considerations must be taken into account at the start of the project so that optimization is built into the project from the start.
  • Long running processes in web parts: make use of the asynchronous programming techniques to run processes in parallel.
  • Accessing the object model:
    - always call .Dispose() on SPSite and SPWeb. These are actually managed wrappers to unmanaged code. The .Net garbage collector does not automatically release these objects in a timely fashion.
    - use the using()statement. This statement automatically calls the .Dispose() method for you.
  • When accessing collections via a property of an object, make a local variable to hold the collection and then access the local object. This going much faster, up to 25% performance increase.
  • Use the Content Query Web Part CQWP): it’s optimized and uses internal caching of queries that no custom web part can achieve, by far.
  • Use output caching in MOSS: this is not active by default but is a great increase in performance and can very easily be activated via the site settings interface.
  • Loading of core files (core.js mainly): this added a runtime by SharePoint but is often not useful for pure front-end WCM sites. There is a workaround to delay load the core.js file so that the rest of the page gets sent to the client and loaded first.
  • When creating WCM sites do not use the default WCM publishing site and those master pages as the basis. These contain a lot of embedded tables that do not load fast. Create a clean master page and CSS files, taking advantage of CSS2 features for example (that’s my own addition here).

That’s a quick list of things to take into account. Spencer will probably post on this on his website so do check out at http://harbar.net


BTW, check out Joris’ blog post about the keynote at TechEd. Some interesting announcements were made there.

 


 


MOSS and SharePoint Services v3 resources page – latest additions

I have been updating my “Resources and tools for WSS 3 and MOSS 2007” page regularly over the last months. Here is a overview of the latest changes.

Additions to the list:

ElBlanco's SharePoint Add-ons
A collection of add-ons for WSS 3.0 and MOSS 2007, although at this time there is only one available: the useful Event Receivers Manager.

Useful Sharepoint Designer Custom Workflow Activities
This CodePlex project provides custom workflow activities for SharePoint Designer.

LINQ to SharePoint
Bart De Smet is working on a tool for using LINQ with SharePoint.

U2UPropertyPagePackage - a feature that adds a List settings page
If you ever needed to get all the details on a list including the ID, properties, content types, site column IDs, and more this feature is for you.

Application Pool Recycle Utility for SharePoint Developers
System Tray utility shows you all the application pools for your IIS and allows you to recycle them via the click of a button.

Updates to resources:

SharePoint Solution Installer: the source code for this tool has now been released via CodePlex.

Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions, Version 1.1 CTP – link added.

And not to forget the updated and revised versions of the WSS3 and MOSS 2007 SDKs:
SharePoint Server 2007 SDK: Software Development Kit
Windows SharePoint Services 3.0: Software Development Kit (SDK)

 

Technorati tags: ,

My session notes on IT-Talks - Installing, administering and working with SharePoint 2007

Yesterday was a day at school. Not actually school but a full day at the IT-Talks user group session “Installing, administering and working with SharePoint 2007”.

It was a one hour drive from where I live, and it was on a Saturday, but there I went. A one-hour drive here in Belgium means I’m almost on the other side of the country :-)
Upon arrival at the location most people were already there so I had to search for a free spot. We were about 25 people assisting to the session, that’s not bad if I may say so.

The idea was to go over a few slides and do all the labs ourselves. However there were some infrastructure problems and the labs weren’t possible. So we mainly watched over on the projector.

The session was presented by Tom Vandaele and Bart Bultink.

Here are a few notes I made during the event, some of them are tips given by Tom, and some I write here as well more as a note for myself:

Installation of MOSS and domain accounts permissions
More a note for myself, but the basic permissions you need when installing MOSS 2007 are:

  • The SharePoint service account (farm account): needs to be a domain user and needs to be added on the SQL server with ‘dbcreator’ and ‘securityadmin’ permissions settings. Nothing more. Tip: also checkout Spencer Harbar's post on this.
  • The SharePoint seach account: needs to be a domain account, nothing more. Extra permissions to the database will be given to this account by the setup program itself.
  • The user account with which you log on to install must be a local Administrator’s member on the server. I guess this one is rather obvious.

Forcing the creation of a new database for each site collection
There is no setting that allows you to say “force creation of new database per site collection”, however there is a very simple way to enforce this. In Central Administration you can set the state of a database to Offline. This does not mean the database itself is stopped or inaccessible, just that it may no longer be used for a new site collection. By setting your databases to offline you force the Administrator to create a new database for each new Site Collection.
Note: just leave one database online for creation of mysites.
Also check out Tom’s post on this. 

Active directory profile import
A good base design of your AD OU structure is very important. For example you cannot import several organization units from a single AD.
Make sure your system accounts are on a separate OU that does not get imported otherwise those accounts will also end up in the search results. And you don’t want that to happen.

Backup/restore
There are two options available for backup/restore of SharePoint sites: SQL Server database backup and WSS backup functionality. None of these do a backup of your custom code so make sure all your custom solution files, web.config changes and the like are also backed up via the hard drive.
SQL database backup: very efficient backup, this is especially a good solution for backup/restore if you store each site collection in a separate database.
WSS backup/restore: takes more time and therefore probably less efficient than SQL database backup. This can be used to transfer a site collection from a staging environment to another.
Using import/export
This is not a backup functionality but may be somewhat linked: using the export/import functionality you can import a site collection as a sub-site of another site collection. This can be a helper if you need to restructure your site content.

Thanks to the organizers!

 

 


WSS3 and MOSS 2007 issue “The Web site wants to run the following add-on: 'Name ActiveX Control'” and how this affected the page load time

During the pre-production version of a public WCM site we were experiencing some strange delay problems with the loading of the first page visited on the site. The MOSS site is configured with dual authentication providers and anonymous access.
When viewing the first request in a session we sometimes had a wait of 20 to 30 seconds (!), the page would load until the body tag, begin loading the CSS and the background would show. After that we had to wait until the rest of the page loaded.
It was really the page loading until background color appeared, then the 20 second wait until the rest of the page was loaded.
My first though was there was something wrong with connectivity to the server but then we were having the same speed problem when requesting the page on the server locally.
We also did some stress testing to see page response times and the results were rather good as well. No server load problem either then.

Some of the test users were also mentioning a problem with an ActiveX control message “The Web site wants to run the following add-on: 'Name ActiveX Control”.

We decided to apply the workaround/solution proposed by the Microsoft KB article 931509: Message in the Information bar in Internet Explorer 7 when you browse to a Windows SharePoint Services 3.0 site or to a SharePoint Server 2007 site: "The Web site wants to run the following add-on: 'Name ActiveX Control'"

Cause of the problem is the Name ActiveX control (Name.dll) that is called by a SharePoint JavaScript file named “init.js”, has not been added to the list of preapproved controls in Internet Explorer 7. The Name ActiveX control is included in the 2007 Microsoft Office system.

There are two workarounds that require changes on the client computer: not a solution for an internet public site.
The third workaround is to adapt a JavaScript file so that the ActivX contol does not get loaded or called anymore. This is the only acceptable workaround for me.

Implementing the workaround

Even if you are using a custom master page chances are you kept the call to the init.js file as this:

<SharePoint:ScriptLink language="javascript" name="init.js" runat="server"/>

This server call generates a <script> tag on the page that fetches the init.js from the locale folder. The ini.js file can be found on the 12 hive, normally “C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033” for a US English version. If you installed a different language or use language packs then replace the 1033 by your locale. Also remember to apply the change to all language packs.

The change that we need to do in this init.js file is simply put the line that makes the ActiveX call in comment. Open up the init.js file (make sure to keep a backup both of the original and your version), locate the following section (it’s the last function in the file):

function ProcessDefaultOnLoad(onLoadFunctionNames)
{
 ProcessPNGImages();
 UpdateAccessibilityUI();
 ProcessImn();
 for (var i=0; i < onLoadFunctionNames.length; i++)
 {
  var expr="if(typeof("+onLoadFunctionNames[i]+")=='function'){"+onLoadFunctionNames[i]+"();}";
  eval(expr);
 }
 if (typeof(_spUseDefaultFocus)!="undefined")
  DefaultFocus();
}

Put the ProcessImn() function call in comment:

function ProcessDefaultOnLoad(onLoadFunctionNames)
{
 ProcessPNGImages();
 UpdateAccessibilityUI();
 //ProcessImn();
//rest of function

This is not exactly the proposed workaround by the KB article but I don’t really get their approach of just putting the function declaration in comment. I don’t even think that will work correctly since the function call still exists and will probably give a JavaScript error (or maybe I’m just missing something there). Anyway, IMHO putting the function call itself in comment is more effective.
I should mention also that creating the new initNoPresence.js file and using that instead of the ini.js in the master page did not have effect. I did not look further into that and just applied the change to the init.js itself.

What’s the result?

In our case applying this change to the init.js file has eliminated the page loading speed problem in IE7. And even with IE6 we see a big difference in loading time of the page.
So be sure to apply this change if you have a public internet site, a small change that can make a difference.

 

Technorati tags: , , ,

 

 


IT-Talks session on SharePoint 2007 Administration

Cross-posted from Joris' blog - guess some extra publicity can never hurt.

The Belgian user group IT-Talks is hosting a session titled "Installing, administering and working with SharePoint 2007" on 8th of September 2007.
Having a more developer focused knowledge on SharePoint server 2007 I think this session will be very interesting to get to know more about the installation part.

It's on a Saturday but anyway, see you there!

 


Custom Web Part: creating and deploying an ASP.NET 2.0 web part with a custom EditorPart for SharePoint 2007 and WSS3

In this post I’ll create a sample ASP.NET 2.0 web part with a custom EditorPart. Source code is available at the bottom of this post.
If you developed SharePoint 2003 (and WSS2) web parts you might know the functionality as ToolParts and the toolpart pane. There is an article on MSDN on how to create your custom ToolPart () by using the WSS2 web part base class. Although you can still use this when developing SharePoint 2007 or WSS3 web parts it is generally recommended to use the ASP.NET 2.0 base class.
The good news is when you build an ASP.NET 2.0 web part you can use it within or without SharePoint.

What does this sample contain? The web part displays a banner image and line of text. The banner URL and a choice of a month is done via the custom web part editor.
I’m deploying the web part assembly to the bin directory (not the GAC) and setting custom CAS security, all that put together in a SharePoint solution.
The web part itself is therefore usable in any ASP.NET project but the deployment part of this post is specific to MOSS and WSS3.

Creating the Visual Studio 2005 project
To develop custom web part(s) create a new class library project. Configure the namespace and assembly name in the solution properties window.
I normally delete the default class1.cs file and create any needed files from scratch.
Open the AssemblyInfo.cs file and add the following code at the end of the file:

[assembly: System.Security.AllowPartiallyTrustedCallers()]

We need to add this attribute because the assembly will be deployed to the local bin directory and give partial trust.

Adding properties to the editor pane via attributes
By using attributes on public properties of the web part you can have editable properties (in personal or shared mode). This can be achieved by adding the following properties to a public property:

[WebBrowsable(true)]

Personalizable(PersonalizationScope.Shared)]

public string BannerUrl

{

  get { return _bannerUrl; }

  set { _bannerUrl = value; }

}

This will automatically add any strings as textboxes in the toolpart pane, in the section Miscellaneous.
You can use these attributes for simple properties where you don’t require validation. String and int will automatically show a TextBox control. Enums will show in the form of a dropdown list.

Sample of how properties are automatically rendered in edit mode:

webpart_edit_properties

Implementing CreateChildControls and RenderContents
In my sample I’m overriding the CreateChildControls method to create constituent controls and then RenderContents method to render them to the page. There is some HTML being written to the page, you may want something fancier than a table so this is just a simple example.

protected override void CreateChildControls()

        {

            base.CreateChildControls();

 

            imageBanner = new Image();

            labelMonth = new Label();

            labelError = new Label();

 

            if (string.IsNullOrEmpty(_bannerUrl) || _month == 0)

            {

                labelError.Text = Properties.Resources.webpart_configuration;

            }

            else

            {

                imageBanner.ImageUrl = _bannerUrl;

                DateTime month = new DateTime(DateTime.Now.Year, _month, 1);

                labelMonth.Text = string.Format(Properties.Resources.editor_monthlabel, month.ToString("MMMM"));

                labelMonth.Font.Bold = true;

                labelMonth.Font.Size = FontUnit.XLarge;

            }

 

            //set ChildControlsCreated to true so that ASP.NET does not call method twice

            this.ChildControlsCreated = true;

        }

 

        protected override void RenderContents(System.Web.UI.HtmlTextWriter writer)

        {

            if (string.IsNullOrEmpty(labelError.Text))

            {

                writer.Write("<table border=1><tr><td>");

                imageBanner.RenderControl(writer);

                writer.WriteLine("</td></tr>");

                writer.WriteLine("<tr><td");

                labelMonth.RenderControl(writer);

                writer.WriteLine("</td></tr></table>");

 

            }

            else {

                labelError.RenderControl(writer);

            }

 

            this.EnsureChildControls();

        }

Adding a resource file
As this web part may be implemented in a different language at a later stage I normally add a resources file for any text used in the control.
Go to Project properties in Visual Studio 2005 and click the Resources item in the left. Click on the text to create a new resource file.

webpart_resources

Any strings used in the control can now be entered here. Accessing the strings in the file can be done like this:

this.Title = Properties.Resources.editor_title; 

This is best the approach when building the web part to be available in multiple languages. Always create a base resources file “Resources.resx” and then add needed languages in the following format: Resources.[language]-[COUNTRY].resx (Resources.en-US.resx, Resources.nl-NL.resx).

Creating the EditorPart class
By creating a custom EditorPart you can choose if you want to show checkboxes, dropdowns, textboxes or other types of controls. You may also add validation for required fields.

Add a new class to the project, in my sample: BannerEditorPart.cs

This control inherits from the base class System.Web.UI.WebControls.WebParts.EditorPart.
Implement the constructor:

public class BannerEditorPart : System.Web.UI.WebControls.WebParts.EditorPart

    {

        public BannerEditorPart()

        {

            this.ID = "BannerEditor";

            this.Title = "Banner properties";

        }

 

    } 

Note: be sure to set the ID property of the EditorPart. Although this does not seem to be a required property in ASP.NET, it will return an error when going to edit mode in a SharePoint web.

Override CreateChildControls() and RenderContents() as in the web part. Two extra methods are overriden in order to save changes to the properties.

public override void SyncChanges()

        {

 

            EnsureChildControls();

            BannerWebpart editorPart = WebPartToEdit as BannerWebpart;

            if (editorPart != null)

            {

                textImageUrl.Text = editorPart.BannerUrl;

                if (editorPart.Month != 0)

                {

                    dropdownMonth.SelectedValue = editorPart.Month.ToString();

                }

            }

        }

 

        public override bool ApplyChanges()

        {

 

            EnsureChildControls();

            BannerWebpart editorPart = WebPartToEdit as BannerWebpart;

            if (editorPart != null)

            {

                try

                {

                    editorPart.BannerUrl = textImageUrl.Text;

                    editorPart.Month = Convert.ToInt32(dropdownMonth.SelectedValue);

                }

                catch (System.Exception exc)

                {

                    _displayErrorMessage = true;

                    error = "Error: " + exc.Message;

                    return false;

                }

            }

            return true;

        }

Final step is to implement the IWebEditable interface on the web part BannerWebpart class and implement the CreateEditorParts method and the WebBrowsableObject property.

object IWebEditable.WebBrowsableObject

        {

            get { return this; }

        }

 

        EditorPartCollection IWebEditable.CreateEditorParts()

        {

            if (this.WebPartManager.Personalization.Scope == PersonalizationScope.Shared)

            {

                List<EditorPart> customEditorPartCollection = new List<EditorPart>();

                customEditorPartCollection.Add(new Demo.Webparts.BannerEditorPart());

                EditorPartCollection editorPartCollection = new EditorPartCollection(customEditorPartCollection);

                return editorPartCollection;

            }

            else

            {

                return null;

            }

        }

Building the manifest.xml and SharePoint solution (.wsp)

Strong name the assembly: go to Project Properties > Signing > Sign the assembly.

The SharePoint solution will install the web part using a .webpart file. In this file we need to add the public token of the assembly. To get the public key use you can use Reflector (see Resources).
XML for the BannerWebpart.webpart file:

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

<webParts>

      <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">

            <metaData>

                  <type name="Demo.Webparts.BannerWebpart, Demo.Webparts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bc0f0ce76789c794" />

                  <importErrorMessage>Cannot import web part.</importErrorMessage>

            </metaData>

            <data>

                  <properties>

                        <property name="Title" type="string">Demo web part - banner</property>

                        <property name="Description" type="string">

                              This is a demo web part

                        </property>

                        <property name="ChromeType">None</property>

                  </properties>

            </data>

      </webPart>

</webParts>

This .webpart file needs to go into the .wsp solution file along with the assembly file. But first we need to create the manifest.xml file in which we add a <Assemblies>, <SafeControls>, and <DwpFiles> sections and the Code Access Security (CAS) elements.

<Solution xmlns='http://schemas.microsoft.com/sharepoint/' SolutionId='guidhere'>

    <Assemblies>

        <Assembly DeploymentTarget='WebApplication' Location='Demo.Webparts.dll'>

        <SafeControls>

      <SafeControl Assembly="Demo.Webparts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bc0f0ce76789c794" Namespace="Demo.Webparts" TypeName="*" Safe="True" />

</SafeControls>

 

        </Assembly>

    </Assemblies>

    <DwpFiles>

        <DwpFile Location='BannerWebpart.webpart'/>

    </DwpFiles>

<CodeAccessSecurity>

      <PolicyItem>

      <Assemblies>

                        <Assembly Name="Demo.Webparts" />

                  </Assemblies>

                  <PermissionSet class='NamedPermissionSet' Name='Demo permission set' version='1' Description='Demo web part trust'>

                        <IPermission

                    class="AspNetHostingPermission"

                    version="1"

                    Level="Medium"

                            />

                        <IPermission

                                    class="DnsPermission"

                                    version="1"

                                    Unrestricted="true"

                            />

                        <IPermission

                                    class="SecurityPermission"

                                    version="1"

                                    Flags="Assertion, Execution, ControlThread, ControlPrincipal, RemotingConfiguration, UnmanagedCode"

                            />

 

                        <IPermission class="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

                         UnsafeSaveOnGet="True" ObjectModel="True" version="1" />

 

                        <IPermission class="WebPartPermission"

                                    version="1"

                                    Connections="True"

                            />

                        <IPermission

                              class="WebPermission"

                                    version="1">

                              <ConnectAccess>

                                    <URI uri="$OriginHost$"/>

                              </ConnectAccess>

                        </IPermission>

 

                  </PermissionSet></PolicyItem>

</CodeAccessSecurity>

</Solution>

Once we have the manifest file we can build the .wsp file using MAKECAB.EXE for example. The cabinet definition (cab.ddf) file looks like this:

;

.Set CabinetNameTemplate=Demo.Webparts.wsp

.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory

.Set CompressionType=MSZIP;** All files are compressed in cabinet files

.Set MaxDiskFileCount=1000 ; Limit file count per cabinet

.Set UniqueFiles='OFF'

.Set Cabinet=on

.Set DiskDirectory1=.

"C:\My Documents\Visual Studio 2005\Projects\Demo.Webparts\
Demo.Webparts\SOLUTION\DLLS\Demo.Webparts.dll"      "Demo.Webparts.dll"

"C:\My Documents\Visual Studio 2005\Projects\Demo.Webparts\Demo.Webparts\
SOLUTION\DwpFiles\BannerWebpart.webpart"      "BannerWebpart.webpart"

"C:\My Documents\Visual Studio 2005\Projects\Demo.Webparts\
Demo.Webparts\SOLUTION\manifest.xml"  "manifest.xml"

;*** <the end>

Build the .wsp file in command line or using a batch file:

makecab.exe /F cab.ddf

The final step is to install the solution and deploy it to the desired web application. There are two ways to do this: in command line using STSADM or using the nice tool by Mondosoft SharePoint Solution Installer .

Here is an example of the web part, very simple content but you get the idea.

webpart_editor_custom   webpart_final

Download the source code here: SampleDemoWebparts.zip

Some resources worth checking out:

ASP.NET Quickstarts tutorials – Personalizing Using Web Parts
http://quickstarts.asp.net/QuickStartv20/aspnet/doc/webparts/default.aspx

You might want to check out this blog post by Dimitri Andreev: WSS 3.0 webparts development
http://blogs.msdn.com/dmandreev/archive/2006/12/07/wss-3-0-webparts-development.aspx
Dimitri gives an overview on the most important differences of ASP.NET 2.0 web parts and SharePoint web parts (using the Microsoft.SharePoint.WebPartPages base class), as well as how to deploy your web parts.

 

Technorati tags: , , , , ,

 

 


Programmatically uploading an attachment to a list item in WSS3/MOSS 2007

If you need to upload a file into a SharePoint document library through code you can get started with this MSDN article: How to: Upload a File to a SharePoint Site from a Local Folder.

In case you need to do the upload the file as an attachment to a custom list using the object model, the approach is slightly different. Adding a file to the list item can be done by accessing the Attachments collection of the SPListIem:

//code snippet
SPList list = web.Lists[
new Guid("my list id")];
if (list != null
)
{
  web.AllowUnsafeUpdates =
true
;
  SPListItem item = list.Items.Add();
  item["Title"] = "my title";

 if (fileAttachment.PostedFile != null && fileAttachment.HasFile)
  {
    
Stream
fStream = fileAttachment.PostedFile.InputStream;

     byte[] contents = new byte[fStream.Length];
     fStream.Read(contents, 0, (
int
)fStream.Length);
     fStream.Close();
     fStream.Dispose();

     SPAttachmentCollection attachments = item.Attachments;
    
string fileName = Path.GetFileName(fileAttachment.PostedFile.FileName);
    
attachments.Add(fileName, contents);

   }

  item.Update();
  web.AllowUnsafeUpdates =
false;

}

//snippet end

 


Running SPSecurity.RunWithElevatedPrivileges in WSS3

When developing a web part or a custom control in WSS/Sharepoint 2007 you might sometimes need to execute some code for which you need more permissions than the one your current user has.
I have this regularly when creating custom controls for Internet Publishing sites in which the anonymous user is the one visiting the site. Say for example that a form is presented to the user that should create new items in a list. An anonymous user does not have a create permission for the list (and we don't want to give the right either).

This can be solved by impersonating the Sharepoint\system user by using the SPSecurity.RunWithElevatedPrivileges method.
MSDN documentation for the method: SPSecurity.RunWithElevatedPrivileges Method (Microsoft.SharePoint).

I ran into a small problem with this method by using it incorrectly… yes my own fault of course but I thought to post an item on this.

Instead of following the example on the MSDN documentation I was using the current context to get an SPWeb object. This does not work because the context has already loaded with the current (anonymous) user’s credentials:

SPSecurity.RunWithElevatedPrivileges(delegate() {
 using (SPSite site = SPControl.GetContextSite(this.Context))
 {

 //implementation here

 }
});

So, always use the web’s ID or URL to load the SPWeb of SPSite object and it works. Just as the documentation shows:

 

SPSecurity.RunWithElevatedPrivileges(delegate()
{
 using (SPSite site = new SPSite(web.Site.ID))
 {

 // implementation details omitted

 }
});

 

Technorati tags: , ,

 


Workflow development in WSS3 and SharePoint 2007 : resources and links

This week I’m starting with the development of my first workflow in MOSS 2007. It’s an extensive topic for which I’m reading as much information as possible. As I’m gathering links and resources I’m posting some of the links I’ve found so far.

Development tools: first things first. In order to get started with custom workflow development:

WSS3 SDK: this SDK also contains the “Workflow Developer Starter Kit for Windows SharePoint Services 3.0” which installs 2 Visual studio templates for workflow:
- Sequential Workflow Library
- State Machine Workflow Library
Installing the SDK also adds the Sharepoint specific workflow activities to the Visual Studio toolbox.

ECM Starter Kit: contains 13 sample workflows using InfoPath forms and 1 sample using custom ASPX pages: http://www.microsoft.com/downloads/details.aspx?familyid=6D94E307-67D9-41AC-B2D6-0074D6286FA9&displaylang=en
These samples are a great way to start learning about how to develop workflows.

Visual Studio 2005 extensions for .NET Framework 3.0 (Windows Workflow Foundation)

Some links:

MSDN: Workflow Configuration Schema Overview (<workflow> schema element) 

Workflow related articles (amongst which a series of 7 posts) on the Microsoft SharePoint Products and Technologies Team Blog

SharePoint 2007 and Windows WorkFlow Foundation: Integrating Divergent Worlds: article by Gustavo Velez. Guides you through the basic process of building a workflow for MOSS using Visual Studio.


Technorati tags: , ,


Belgian user groups: Community day event

Today the first Belgian community day organized by five user groups was held in Keerbergen. What a day to get to the destination! Keerbergen is a village located next to Werchter where the yearly Rock Werchter festival takes place.
And today was the first day of the festival so there were a lot of cars stuck in the small roads leading to the festival. But I was lucky because most of the traffic jams were in the opposite direction.
And then again not so lucky because I don't have tickets to the festival ;-)

So now back to the event, it was a good opportunity to network with peers and learn something new in one of the technical sessions.

First session: SharePoint Community tools (BIWUG)
Joris Poelmans presented a general overview of development tools that can be used to help on SharePoint and WSS development. A few of the tools I already use and are listed in my Resources page. The new ones I did not yet know were:

  • AppPool recycler for SharePoint Devs: a little tool that sits in the windows tray and lets you choose an IIS application pool to recycle without having to go via IIS or doing an IISRESET.
  • WSPBuilder: a Visual Studio project template that builds your manifest.xml, ddf and cabinet file ollowing a 12 hive directory structure.
  • U2U CAML Query Builder feature: a SharePoint feature that adds action to build a CAML query via the interface and then saves the query to a document library. The query is then available for use in your custom developments. This is a feature developed by CAML Girl who was present in the audience!

Second session: Visual Studio Team System software lifecycle (VISUG)
Pieter Gheysen presented Visual Studio Team system in the new Visual Studio 2008 (using the Orcas VPC). Nice overview of the functionalities.

After that there was a nice dinner and time to network and get in contact with new people.
Thanks to the organizers!

 


New WSS3 development article on MSDN by Patrick Tisseghem and updated MOSS resources list

While catching up with new items in my RSS reader I learned that Patrick Tisseghem has just released another fantastic article series about WSS3 on MSDN:

These two articles go over the development process for WSS3 and MOSS 2007: setting up the development environment, basic development tools (Visual Studio Extensions for WSS3), using features, custom field controls, packaging it all into solutions (.wsp) and even a small sample on setting Code Access Security for web parts. Wow!
A must read for everyone starting out or already doing WSS3 development.

At the same time I've also updated my own list of WSS3 and MOSS 2007 resources I'm trying to keep up to date. It's not yet an extensive list of tools available but I'm trying to keep the list updated with tools I've already tried out.

 

Technorati tags: , , , ,

 


Problems with ClientScriptManager.GetWebResourceUrl in MOSS 2007 webparts (anonymous sites)

I have been struggling with some errors when using embedded resources in MOSS web parts.

My web part uses the ClientScriptManager.GetWebResourceUrl method to access an embedded resource. In this case it’s a JavaScript file that is compiled into the assembly.

Code snippet:

protected override void RenderWebPart(HtmlTextWriter output)

{

EnsureChildControls();

ClientScriptManager manager = this.Page.ClientScript;

string jsLibraryUrl = manager.GetWebResourceUrl(this.GetType(), "myresouce...");

string jsLibrary = string.Format("<script type=\"text/javascript\" language=\"JavaScript\" src=\"{0}\"></script>", jsLibraryUrl);

output.Write(jsLibrary);

//rest of code...

}

  • The web part is deployed to the web application’s bin directory by using a SharePoint solution.
  • Code Access Security for the web part’s assembly is set in the solution manifest.
  • My application is accessible by two Security Zones: Default and Internet. The Internet zone has been configured for Anonymous access.

Note: if you don’t know what and how embedded resouces can be used in ASP.NET 2.0 this is a good article from ASPAlliance.com: Embedding Resources in ASP.NET 2.0 Assemblies.

After development testing and deploying the web part on the web application I access the URL by using the Default zone and log in as an administrator. My web part works fine.
Next I log in by using the web application URL that has been extended and configured for anonymous access. Here I run into an error, a blank page is displayed showing just a 403 error.

403 FORBIDDEN

I went into debug mode and put a breakpoint in the CreateChildControls method of the web part. There I found that an exception was being generated by the following line:

string jsLibraryUrl = manager.GetWebResourceUrl(this.GetType(), "myresouce...");

The exception was System.UnauthorizedAccessException.

To resolve this I tried adding Read permissions to the IUSR_computername and the ASPNET users to the /bin directory of my web application. This solved the problem but is not a solution I can use on a production environment. Every time a new SharePoint solution is deployed to the web application the file permissions on the bin directory are reset by SharePoint anyway.

I googled for answers from people having similar problems. On a very nice post by Ryan Rogers about embedded resources there is a comment from someone with the same issue. There is no answer to the comment. Bummer… the problem is exactly the same as mine but no solution :-(

I tried installing the assembly in the GAC and this also solved the problem. As this is not an option for production I continued searching for other solutions.
After some more trial an error with CAS configuration I decided to use the SPSecurity.RunWithElevatedPrivileges method around the code calling the web resource.

Using this in combination with the Impersonate="true" in the SharePointPermission in CAS does it! Not setting the impersonation will raise a security exception when calling RunWithElevatedPrivileges.

This is what I ended up doing:

try

{

  SPSecurity.RunWithElevatedPrivileges(delegate()

{

  ClientScriptManager manager = this.Page.ClientScript;

  jsLibraryUrl = manager.GetWebResourceUrl(this.GetType(), "myresouce...");

});

}

catch (System.Security.SecurityException exc)

{

  System.Diagnostics.Trace.Write(exc.ToString());

}

CAS element:

<IPermission class="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

UnsafeSaveOnGet="True" AllowUnsafeUpdates="True" ObjectModel="True" version="1" Impersonate="true" />

I’m still wondering if this is the good approach but since no other solution is available for the moment I’m happy with it.
If someone has a better solution I would love to hear about it.


 


Event handlers in WSS3 and MOSS 2007: some general notes and preventing a user update

Last week I was working on an event handler to prevent users from changing a value of a custom list item one an external service is busy processing some data.

Reading some information on event handlers I learned some important aspects about event handlers.

Deploy to the GAC: the assembly containing the event handler must be deployed to the Global Assembly Cache.

-Ed en -Ing events (asynchronous and synchronous events)
Event names ending on –ed like ItemUpdated, ItemDeleted and so on are called asynchronous events as they will execute after the action has been completed. At this stage you can no longer prevent something from being save or deleted.
The events ending in “ing” like ItemUpdating, ItemInserting and so on fire before the action is completed and are therefore called synchronous. In this case you can still intervene before the action is final.
The full list of available methods that can be overridden for SPItemEventReceiver can be found in the following MSDN article: http://msdn2.microsoft.com/en-us/library/ms437502.aspx

DisableEventFiring()
If you need to do an update to an item from within your event receiver you might end up in a recurring event being fired for the updates. To prevent this you can call DisableEventFiring() and then EnableEventFiring(). A small example for this:

public override void ItemUpdated(SPItemEventProperties properties)

        {

            //some handling here

            ListItem item = properties.ListItem;

            item["someproperty"] = "some value";

 

            this.DisableEventFiring();

            //save changes

            addedItem.Update();

            this.EnableEventFiring();

 

        }

When calling the Update method you might also consider using SystemUpdate() method which will do a SharePoint database updating without updating the time modified or versions of the item.

So now back to my event handler: I was looking for a way to know from within the event handler if it had been fired by a user action or by a system update. A system update is in my case a windows service opening the list item by using the object model.
As I’m using a schema.xml file to create the custom list I added a boolean field with the ReadOnly attribute set to true. This makes the custom field hidden in the edit form for the list item. When updating the item through the object model I do have access to the custom readonly field and can set its properties.

schema.xml snippet:

    ... ...

<Fields>

  <Field ID="{1FFDF566-D220-45e0-814D-34DB0E1A253D}" Name="Myreadonlyfield" StaticName="Myreadonlyfield" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="Groupname" DisplayName="SystemUpdate" Description="Hidden system field" Type="Boolean" ReadOnly="TRUE" Sealed="TRUE"></Field>

    </Fields>

       ...

</Fields>

My custom application sets the read only field to true before calling Update:

  item["fieldx"] = “some update”;

  item["SystemUpdate"] = true;

  item.Update();

As I’m using a synchronous event handler I can change the AfterProperties before these are saved into the database. This prevents the field from having a “true” value next time the item is updated.

public override void ItemUpdating(SPItemEventProperties properties)

       {

            bool isServiceUpdate = false;

            string modifiedStatus = Convert.ToString(properties.AfterProperties["somestatusfield"]);

 

            isServiceUpdate = Convert.ToBoolean(properties.AfterProperties["Myreadonlyfield"]);

 

            // Myreadonlyfield is always set to false except when the update comes from my custom application

            if (isServiceUpdate == false)

            {

 

                if (modifiedStatus.ToLower() == "invalid")

                {

                    properties.ErrorMessage = "This is an invalid choice...";

                    properties.Cancel = cancel;

                }

 

            }

            else

            {

                properties.AfterProperties["Myreadonlyfield"] = false;

            }

 

       }

I’m thinking maybe there is a much more efficient way of doing this but as I did not find any this way my solution. And what counts is it does the work.


And then here is a fantastic article series I found recently with very good information about event handlers in SharePoint 2007:
Brian Wilson - Event Handlers - Part 1: Everything you need to know about Microsoft Office SharePoint Server (MOSS) Event Handlers.

 

Technorati tags: , ,

 


Going to the Belgian Community Day

Coming 28th of June 2007, five IT Belgian User Groups are organizing a community day: BIWUG, VISUG, SQLUG, IT-Talks and Pro-Exchange. It's the first time I'll be attending a community and apparently it's also the first time the five groups are organizing a day together.

I'm a member of two of them: BIWUG and VISUG but been to more meetings organized by BIWUG. It's a really nice way to get to know people in the same work field and exchange experiences about our projects.

Looking forward to the event for the learning and the socializing with peers :-) 
See you there.

Register at: www.communityday.be

 

Technorati tags: , , , ,

Part III – MOSS 2007 Publishing page layout using a feature

This is the third and last post on creating site columns, publishing content types and page layouts using features:
Part I – Creating site columns, publishing content types and page layout using a feature
Part II – Creating publishing content types

This post describes how to create a publishing page layout and deploy it using a custom feature. This post goes further on what was already discussed in pat I and II. Now that we have a custom publishing site columns as well as custom publishing content types defined using a feature, the next step is to create the page layout.

Publishing page layouts map to the custom fields of a publishing content type. The files are placed in the Master page gallery (Site Actions > Site Settings > Modify All Settings > Galleries section > Master pages and page layouts).

1. Creating the page layout

The page layout can be created by using Visual Studio 2005. It’s really an .ASPX page and some basic Intellisense works for the SharePointWebControls and PublishingWebControls.
If you need information on how to create your custom page layout there is a very good article on MSDN: Customizing and Branding Web Content Management-Enabled SharePoint Sites (Part 1 of 3): Understanding Web Content Management and the Default Features.

Important to remember here is that you are dependant from the Master Page that will be used together with your page layout. In this article I’m using the default Blue Bland one; so all the default Content placeholders are available.

Snippet of the page layout (download all the files from the link at the bottom of the post):

Tip: to quickly create and test a page layout for my custom content types I sometimes use SharePoint Designer 2007 (SDP). Create the page layout by choosing “New > Page Layout” in the Master pages gallery. Be sure to choose your custom page layout:

Then open the page using SharePoint Designer. Add your HTML and design elements and drag your custom properties to the page. HTML page design is really not my thing so this is an easy way to add some tables and layout to the page. Once you have the page ready in SPD, save the file, check in and test it by creating a new page.
You can now use the HTML and controls from this page when creating your custom page layout using Visual Studio.
Note that SPD saves the page directly into the SharePoint database and not on the hard drive. So this is just a fast way to start up the creation of your page layout but it does not allow you to deploy the page easily to other servers.

2. Creating the provisioning xml schema

To provision the page layout and any used CSS, images or other files we create a XML file that will be picked up by the feature and install the files in the corresponding libraries in your publishing site.

In my example I have one custom page layout with just one image. I could as well have several images and CSS files installed using the same feature. I guess you get the idea with this image sample.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

 

    <Module Name="ProductPageLayouts" Url="_catalogs/masterpage" Path="PageLayouts" RootWebOnly="TRUE">

 

                                <File Url="ProductDetail.aspx" Type="GhostableInLibrary">

                                                <Property Name="Title" Value="$Resources:pagelayout_product_name;" />

                                                <Property Name="MasterPageDescription" Value="$Resources:pagelayout_product_description;" />

                                                <Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />

                                                <Property Name="PublishingPreviewImage" Value="~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/DefaultPageLayout.png, ~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/DefaultPageLayout.png" />

                                                <Property Name="PublishingAssociatedContentType" Value=";#$Resources:contenttype_productbase_name;;
#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB0645
84E219954237AF3900ADB88465BE2C439798977662094183BC;#
"/>

                                </File>

 

                </Module>

                <Module Name="ProductLayoutImages" Url="Style Library" Path="Styles" RootWebOnly="TRUE">

                                <File Url="images/line.jpg" Name="product/images/line.jpg" Type="GhostableInLibrary" />

                </Module>

</Elements>

(Note: the value for PublishingAssociatedContentType above contains a break for HTML display reasons. You should put the value in one line)
I must say not much is available in the MSDN documentation about the schema for provisioning publishing pages. Like in other cases I looked at the PublishingLayouts feature delivered with the MOSS 2007 installation. This is a hidden feature that provisions the standard page layouts, master pages, etc for a MOSS Publishing site. You can find the feature here: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\PublishingLayouts.

Some clarifications to the schema elements:

<Module> element

<Module Name="[your module name]" Url="virtual path destination of the module elements " Path="path from within this feature">

PublishingAssociatedContentType property
This property specifies to which the page layout you are installing is mapped to. The syntax is
;#ContentTypeName;#ContentTypeID;#

GhostableInLibrary
Every <File> element has the property Type="GhostableInLibrary"
This property is important because it will install the file in the Master Page gallery, but the actual file content are still stored on the hard drive and not directly in the SharePoint database (as is the case if you create your page layout using SDP).

3. Wrapping it up: creating the feature

I’m using one single feature to create my custom publishing fields, custom publishing content type and custom page layout(s).

The feature now has the following structure:


Three XML files are referenced by the feature schema in the order in which they should be installed.

  1. myfields.xml: this file defines all my custom site columns
  2. ProductContentTypes.xml: this file defines my two custom publishing content types and uses the custom field defined in myfields.xml
  3. PageProvisionedFiles.xml: this file contains the provisioning for page layout and associated image

I think the order in which these files are referenced in the feature schema are important because the site columns must be created before the content types, and the content types must be created before the page layout can reference it.
So, I have no proof that this really executes in the order defined in the feature schema but I do assume it is the case. Maybe someone has found some documentation on this?

Feature schema:

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

<Feature  Id="787DCDC4-97F9-4f64-A771-D2A8B86DCADB"

          Title="My publishing content type"

          Description="$Resources:feature_description;"

          Version="1.0.0.0"

          Scope="Site"

          DefaultResourceFile="_Res"

                                  Hidden="FALSE"

          xmlns="http://schemas.microsoft.com/sharepoint/">

                <ActivationDependencies>

                                <!-- Add a dependency to the Publishing site-->

                                <ActivationDependency FeatureId="F6924D36-2FA8-4f0b-B16D-06B7250180FA" />

                </ActivationDependencies>

                <ElementManifests>

                                <ElementManifest Location="myfields.xml"/>

                                <ElementManifest Location="ProductContentTypes.xml"/>

                                <ElementManifest Location="PageProvisionedFiles.xml"/>

                </ElementManifests>

</Feature>

That’s it, the feature is complete.
All that needs to be done is copy the feature directory to “C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\MyContentTypeFeature” and run the install command
 
stsadm -o installfeature -filename MyContentTypeFeature\feature.xml

This command can be used to install and test the feature. For a production environment I would recommend creating a SharePoint solution that installs the feature and all its files.

The feature can be downloaded here: publishingfeature.zip.
The zip file contains all the files discussed in the three posts as well as a batch file that installs and activates the feature. Just update the URL to your site name first.

 


MOSS 2007 trial key expired – update license causing error

Yesterday my trial license key for SharePoint 2007 (MOSS) expired, right in the middle of the day!
I was expecting this but ran into a problem with the license key update. Good news was someone posted about the same issue just this Monday and I found it via Google. I didn’t know Google was this fast in indexing content!

If you are also running into this problem this is the link to Shane’s “The SharePoint Farmer’s Almanac” blog where he has a solution: http://msmvps.com/blogs/shane/archive/2007/05/29/problems-with-licensing-moss.aspx

Here are the details of my issue with the trial license update.

After entering the new license key for the Enterprise version in the Central Administration and clicking OK the update in progress screen was shown for about 5 minutes (yes 5!). After completion I just got a rather generic error message in the sort of “An error occurred please check the log for details”.

I first checked the Event viewer for more information, found the error but not much was shown:

Not much in here so I checked the log file for more details.
The log file can be found in the 12 hive > LOGS directory (normally C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\LOGS)

Here more details were available:

05/30/2007 11:45:31.15             OWSTIMER.EXE (0x0B5C)                               0x158C Office Server                             Setup and Upgrade                 7fwn     High    Executing the Trial Conversion Job.       
05/30/2007 11:45:31.20             OWSTIMER.EXE (0x0B5C)                               0x158C Windows SharePoint Services   Timer                                     7psa     Critical  The Execute method of job definition Microsoft.Office.Server.Administration.LicensingConversionJob (ID e9a304e0-b90e-4787-969c-372f6d27e6e2) threw an exception. More information is included below.  Arithmetic operation resulted in an overflow.  
05/30/2007 11:45:31.20             OWSTIMER.EXE (0x0B5C)                               0x158C Windows SharePoint Services   Timer                                     72ae     Unexpected      Exception stack trace:    at Microsoft.Office.Server.Administration.Licensing.RecordSqmDataPoints(Boolean trialConversion)     at Microsoft.Office.Server.Administration.Licensing.ConvertTrialToLicensed()     at Microsoft.Office.Server.Administration.LicensingConversionJob.Execute(Guid targetInstanceId)     at Microsoft.SharePoint.Administration.SPTimerJobInvoke.Invoke(TimerJobExecuteData& data, Int32& result)
 

As the error details did not guide me towards a solution I opened up Google and after 2 clicks found Shane’s post.
So a simple iisreset seems to solve the problem. Would be nice to find the actual problem behind this issue.

 


MOSS 2007 and WSS3 development process: some ideas and tips

As my first SharePoint 2007 WCM project comes an end (for phase 1 that is), I think it is a nice moment to take a step back and post my thoughts on the development process in WSS3 and MOSS 2007.

I’m not going into the details about the project at this stage, in this post I would just like to share lessons learned and my ideas and tips on development.

Before giving my own thoughts, a good article was recently posted on MSDN containing guidelines for team based development on SharePoint 2007: Team-Based Development in Microsoft Office SharePoint Server 2007 (http://msdn2.microsoft.com/en-us/library/bb428899.aspx). I was glad our own approach to SharePoint development was very close to was is recommended, so I won’t go over the same points in this post.

Essential tools and resources
Most of the development helpers and tools I use are already posted in a separate page on this site: see Resources. These are the basic ones every developer in the team had to install:
- Visual Studio 2005 WSS3 Extensions
- The WSS3 SDK
- SharePoint 2007 SDK and the ECM Starter Kit. The starter kit contains some nice code samples.
- Reflector.Net for digging into the SharePoint classes when documentation was well, not very extensive.

I bundled my ideas in a few tips:

Tip 1: Build and test your development by using solutions
During development of custom features, application pages, web parts etc we used batch file based installation files. We used XCOPY for installing custom features, custom pages in the layouts directory, the gacutil.exe for registering and so forth. This works fine at first but as you eventually will need to combine all those developments into a SharePoint solution don’t wait on that. Create the solution from the start so that your installation process gets tested. The nice thing about solutions is that when you uninstall the solution all installed files get nicely deleted/cleaned from all the SharePoint 12 hive directory. No need to manually go through the installation directories and delete custom layout files, features and the like.

Tip 2: put it all in a solution
Why is this second tip as well as the first? Well I can’t emphasize enough how important it is to integrate as much as possible in the solution. You can add SafeControl sections for webparts, custom config sections, features, add CAS sections that are automatically merged into configuration, add root files that should go into the 12 hive root, site definitions that are nicely installed into the different directories (for site definitions, template files go into ‘C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates’; webtemp*.xml files go into ‘C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\XML’) and so on.

Tip 3: CAS for web application assemblies
If you follow the guideline that is to install your custom DLLs in the web application’s bin directory you will need to use CAS (Code Access Security) to define the permissions your assembly gets when running on SharePoint. Don’t start by installing your assembly in the GAC and then moving to the web application later. You’ll probably just lose time when doing the change. CAS might seem extra work in the beginning but is essential to get your assembly to run correctly when installed in the application’s bin directory.

Tip 4: use features
This might as well been tip # 1, everything can be a feature! Features can be used to create content types, libraries, instantiate lists, add event receivers, customize setting, and so on and so on...
Important during the analysis phase: don’t make too many features either. The analysis phase is crucial to correctly separate or combine customizations into features. I would recommend analyzing the benefits of separating elements into features or combining several elements into a single feature.

Tip 5: For multiple language interfaces, test in every language needed
Test your development and customization in every language early in the development process. My own development setup is in English but at the client we are using a Dutch version. This gave us a few small problems as we hadn’t foreseen because sometimes display names are used to access lists or base SharePoint elements.
Use resource files and satellite assemblies for translated elements.

That’s it for now. I have more ideas on this but will put those in another post when I get the time to present them in an orderly fashion.

So what are your ideas on the WSS and SharePoint development?

Technorati tags: , , ,

 


Resources for WCM security on MOSS: securing anonymous sites

[via the Microsoft SharePoint Products and Technologies Team Blog]

Two very good resources on how to correctly implement security for anonymous users on MOSS internet facing websites:

- A guide on Microsoft Technet: Plan security for an external anonymous access environment (Office SharePoint Server) (http://technet2.microsoft.com/Office/en-us/library/f507f5d6-4c9d-4f98-909f-069c53b9a3f61033.mspx?mfr=true)

- A comment with a link to a very good post by Steven Tapping: Restricting Document Library Browsing for SharePoint 2007 Anonymous Users.
Steven gives a step by step overview on how you can correctly enable read access to library items without giving anonymous users the permission to browse the library (http://blogs.vertigo.com/personal/steventap/Blog/Lists/Posts/Post.aspx?ID=22).

 


MOSS 2007 error in event viewer - permission settings do not grant Local Activation permission for the COM Server

[Update July 2007: see below]

Last week we did a clean installation of Microsoft Office SharePoint Server 2007 on a new Windows 2003 server.

After completing installation we found a recurring error message in the Event Viewer regarding two application pool users. The error message states:

The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID

{61738644-F196-11D0-9953-00C04FD919C1}

 to the user [domain\username] SID (S-1-5-21-GUID..).  This security permission can be modified using the Component Services administrative tool.

It seems the application pool user that we used when creating our web application does not have enough permissions on a DCOM component. After a few searches on the net I came to a blog post that solved our problem: http://geekswithblogs.net/mhamilton/archive/2006/12/19/101568.aspx

In our case this resulted in our user not having launch permissions for the service "IIS WAMREG admin service".

I have one idea why this could occur: we used a local windows account for the setup user instead of a domain account. The MSDN documentation recommends a domain account.

Based on the blog post by Mike H. we applied the following steps:

  1. Start-->Run-->regedit
  2. Click “My computer” > Edit > Find > and paste the CLSID {61738644-F196-11D0-9953-00C04FD919C1}
  3. The found item will be opened. Check the name of the service the ID belongs to. In our case it was the IIS WAMREG admin service.
  4. Open Component Services by going to Start > All Programs > Administrative Tools > Component Services.
  5. Expand the tree to Computers > My Computer > DCOM Config.
  6. Search for the service "WAMREG admin service" and right-click Properties.
  7. Choose the Security tab > Customize in the Launch and activation permissions. Click Edit.
  8. A permissions dialog box opens. Add the user name that was mentioned in the Event Viewer.
  9. That solved it for us.

Thanks to Mike H. 

[Update 19 July 2007]
Peter left a comment about a KB article about this issue that is now available: Event ID 10017 error messages are logged in the System log after you install Windows SharePoint Services 3.0. So check out the article at http://support.microsoft.com/kb/920783
Thanks Peter!


MOSS 2007 Publishing web site definition template – onet.xml – syntax for properties and getting the right content types

The documentation for creating site definitions and provisioning for MOSS 2007 Publishing sites is almost non-existing on MSDN.

My first suggestion is to look at the out of the box publishing site definition “BLANKINTERNET”.
This site definition is located in the 12 hive: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\BLANKINTERNET
The template configuration for this site definition can be found in the file: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\XML\webtempsps.xml. Note that only the part in the element <Template Name="BLANKINTERNET" ID="53">... is applicable.

I will post a more complete article on how to create your own publishing site definition with custom page layouts, master pages and content types later when I have more time... For now I’ll just go over the elements on which I had most work getting them to work. It’s actually not quite hard as long as you know how to do it.

1. Make sure the required onet.xml and webtemp*.xml files are copied to the right directories

Your onet.xml file should go into the folder C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\[YOURSITEDEF]\XML
Provisioned files may go one level higher: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\[YOURSITEDEF]

webtemp*.xml file should go into: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\XML

2. onet.xml: referencing the correct site features

In order to get the publishing site features activated when you create a site based on your custom site template, make sure all required publishing site and web features are activated. Features at site level are defined and activated at the site collection level. Web features will be activated for every new web you create using this configuration.

... <!-- part ommitted for clarity -->
<
Configurations>
<
Configuration ID="-1" Name="NewWeb"/>

<Configuration ID="0" Name="[YOURSITEDEF]">

<SiteFeatures>

<!-- Workflow Features -->
<!--
Workflow Expiration -->

<Feature ID="C85E5759-F323-4EFB-B548-443D2216EFB5" />

<!-- Workflow Review -->
<
Feature ID="02464C6A-9D07-4F30-BA04-E9035CF54392" />

<!-- Workflow Signature -->
<
Feature ID="6C09612B-46AF-4B2F-8DFC-59185C962A29" />

<!-- Workflow Translation -->
<
Feature ID="C6561405-EA03-40A9-A57F-F25472942A22" />

<Feature ID="A392DA98-270B-4e85-9769-04C0FDE267AA">

<!-- PublishingPrerequisites -->

</Feature>

<Feature ID="7C637B23-06C4-472d-9A9A-7C175762C5C4">

<!-- ViewFormPagesLockDown -->

</Feature>

<Feature ID="AEBC918D-B20F-4a11-A1DB-9ED84D79C87E">

<!-- PublishingResources -->

<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<
Property Key="AllowRss" Value="false"/>
<
Property Key="SimplePublishing" Value="false" />
</
Properties>

</Feature>

<Feature ID="F6924D36-2FA8-4f0b-B16D-06B7250180FA">

<!-- Office SharePoint Server Publishing -->

</Feature>

</SiteFeatures>

<WebFeatures>

<!-- Include the common WSSListTemplateFeatures used by CMS -->

<Feature ID="00BFEA71-DE22-43B2-A848-C05709900100" > </Feature>

<Feature ID="00BFEA71-E717-4E80-AA17-D0C71B360101" > </Feature>

<Feature ID="00BFEA71-52D4-45B3-B544-B1C71B620109" > </Feature>

<Feature ID="00BFEA71-A83E-497E-9BA0-7A5C597D0107" > </Feature>

<Feature ID="00BFEA71-4EA5-48D4-A4AD-305CF7030140" > </Feature>

<Feature ID="22A9EF51-737B-4ff2-9346-694633FE4416">

<!-- Publishing -->

<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<
Property Key="ChromeMasterUrl" Value="~SiteCollection/_catalogs/masterpage/mymasterpage.master"/>
<
Property Key="WelcomePageUrl" Value="$Resources:cmscore,List_Pages_UrlName;/default.aspx"/>
<
Property Key="PagesListUrl" Value=""/>
<
Property Key="AvailableWebTemplates" Value="*-MYSITEDEF#1"/>
<
Property Key="AvailablePageLayouts" Value="~SiteCollection/_catalogs/masterpage/mypagelayout.aspx"/>
<
Property Key="AlternateCssUrl" Value="" />
<
Property Key="SimplePublishing" Value="false" />

</Properties>

</Feature>

<Feature ID="541F5F57-C847-4e16-B59A-B31E90E6F9EA">

<!-- Per-Web Portal Navigation Properties-->

<Properties xmlns="http://schemas.microsoft.com/sharepoint/">

<Property Key="InheritGlobalNavigation" Value="true"/>

<Property Key="IncludeSubSites" Value="true"/>

</Properties>

</Feature>

<Feature ID="94C94CA6-B32F-4da9-A9E3-1F3D343D7ECB">

<!-- Office SharePoint Server Publishing -->

</Feature>

</WebFeatures>

<!-- remaining elements ommitted -->

</Configuration>

3. The right syntax for AvailablePageLayouts and AvailableWebTemplates

The Publishing Web Feature (ID 22A9EF51-737B-4ff2-9346-694633FE4416) contains some properties that allow us to specify master pages, page layouts and available web templates.

The syntax for specifying the values in the onet.xml file is not documented (as far as I could find).

AvailablePageLayouts

Your custom page layout should be deployed to the site collection by activating a page layout provision feature for example.

For a single page layout, the syntax is available in the BLANKINTERNET site definition:

<Property Key="AvailablePageLayouts" Value="~SiteCollection/_catalogs/masterpage/mypagelayout.aspx"/>

For defining multiple AvailablePageLayouts I found that the separator is : (colon) by looking at the Search site definition (SRCHCEN):

<Property Key="AvailablePageLayouts" Value="~SiteCollection/_catalogs/masterpage/
mypagelayout.aspx:~SiteCollection/_catalogs/masterpage/mypagelayout2.aspx
"/>

AvailableWebTemplates

If you want to restrict the list of available web templates you can do this with the AvailableWebTemplates property.

<Property Key="AvailableWebTemplates" Value="*-MYSITEDEF#1"/>

For specifying multiple web templates, I found the syntax thanks to a post in a forum: http://www.eggheadcafe.com/software/aspnet/29217247/availablewebtemplates-key.aspx

Someone found the syntax by looking at the Microsoft.SharePoint.Publishing.PublishingWeb class using reflector. Snippet from the solution mentioned in the forum:

AvailableWebTemplates Key Format is:
LCID-[sitetemplatename][#sitetemplatenumber];LCID-[sitetemplatename]
[#sitetemplatenumber];LCID-[sitetemplatename][#sitetemplatenumber]

1033-BLANKINTERNET#1;1049- BLANKINTERNET #1;*- BLANKINTERNET #2

*-BLANKINTERNET#2 - ALL Languages
(Thanks Sorgi?)

So if we know the separator is ; (semi-colon) the element should look like:

<Property Key="AvailableWebTemplates" Value="*-MYSITEDEF#1;*-MYSITEDEF#3"/>

Please see the Microsoft.SharePoint.Publishing.PublishingWeb class reference on MSDN: http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.publishingweb.aspx. Looking at the class properties will also give you more insight into how to use the properties in the onet.xml file.

4. Using multiple configuration and hiding them in the UI

The webtemp*.xml file may contain multiple template configurations. You may make some of these hidden for example if you want to create those specific sites via code only. Use for Hidden="TRUE" this.

webtemp*.xml snippet:

<!-- ... snippet:-->

<Template Name="MYSITEDEF" ID="10020">

<Configuration ID="0" Title="My site template" Hidden="FALSE" ImageUrl="/_layouts/1033/images/img.gif" Description="This is a publishing site template" SubWebOnly="FALSE" DisplayCategory="My own category">

</Configuration>

<Configuration ID="1" Title="My site template – Autocreated contact section" Hidden="TRUE" ImageUrl="/_layouts/1033/images/img.gif" Description="This template is used by code to generate the contact site." SubWebOnly="TRUE" DisplayCategory=" My own category" VisibilityFeatureDependency="97B7C2D9-51E6-4add-844E-D133D25B7B15">

</Configuration>

<!-- ... snippet end-->

5. Making your own content types available

When you use custom page layouts chances are you are also using custom content types. By using the AvailablePageLayouts properties your custom page layouts become available but there is still a problem. By default the Pages library only contains the MOSS publishing content types, as you can see in this screenshot:

Users will be available to create new pages using your page layout but all the custom properties you use in their related content types are missing. The page layout may not show any property in edit mode. If you go the Site Settings > Site content types, you will see your custom content types and their site columns.
You may manually add the content types to the Pages library by going to Site Actions > Site Settings > Modify Pages Library Settings. Choose “Add from existing site content types” and choose the content types. Once this is done your custom page layouts should start working normally.
Doing the manual setting is one possibility but having to do this manually for every new web is not really an option.
I ended up creating a web feature that is automatically activated by the site template definition. My feature contains a ReceiverAssembly and class in which I add the desired content types to the Pages library.

Code snippet:

string pageLib = Microsoft.SharePoint.Publishing.PublishingWeb.GetPagesListName(web);

SPContentTypeCollection allContentTypes = web.Site.RootWeb.AvailableContentTypes;

SPContentTypeCollection usedContentTypes = web.Lists[pageLib].ContentTypes;

foreach (SPContentType contentType in allContentTypes)

{

if (contentType.Hidden==false && contentType.Group.ToLower().StartsWith("Mygroupname ") == true)

//if the content type does not yet exist in the library add it:

{

if (usedContentTypes[contentType.Name] == null)

{

web.Lists[pageLib].ContentTypes.Add(contentType);

}

}

}

That’s it for me!

 


WSS3 Custom web.config settings

When we need to add custom settings or sections to the web.config file of a web application in WSS3 and MOSS, there is a way to do this quite automatically.

If you need several settings that you would like to have added to the web application's web.config when creating/extending the web application, custom xml config files can be used for this.

You can create a file in the format webconfig.[name].xml, put it in the \\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG folder and the settings in the file will be merged with the web.config file on any new web application.
Of course if your web application is already created and you put the file in the \config folder no changes are applied. This is really only when creating/extending new web applications.

Even so, this is a very interesting feature as you can automate any custom settings you would like on all your web applications in WSS3.

In my case I needed a custom appSettings element and a new custom connection string. The XML to be used consists of elements placed into the <actions> elements. The syntax is straightforward:

webconfig.myname.xml contents:

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

<actions>

<add path="configuration/appSettings">

<add key="MyFilePath" value="C:\temp\path\" />

</add>

<add path="configuration">

<connectionStrings />

</add>

<add path="configuration/connectionStrings">

<remove name="MySqlServerConnection" />

<add name="MySqlServerConnection" connectionString="server=[server];database=[db];Integrated Security=SSIP;" providerName="System.Data.SqlClient" />

</add>

</actions>

To deploy this file to the CONFIG you can manually copy the file.

Another approach is adding the file to a solution. A file to be deployed to the CONFIG folder can be inserted by using the <RootFile> element:

manifest.xml example:

<Solution xmlns="http://schemas.microsoft.com/sharepoint/" SolutionId="GUIDHERE">

<RootFiles>

   <RootFile Location="CONFIG\webconfig.myname.xml"/>

</RootFiles>

<!-- rest of solution manifest here
<FeatureManifests>... and other elements
-->

</Solution>

This is my approach to automating web.config settings. Just remember the config settings are only merged with the web.config file when you create a new web application, nothing is changed on existing web applications.
Contrary to the <SafeControls> elements you can use in a solution manifest, these are always merged to the web.config file when you deploy the solution.

MSDN reference for custom configuration settings: http://msdn2.microsoft.com/en-gb/library/ms439965.aspx


 

Technorati tags:

<solution> deployment error to the GAC: Error: Cannot add the specified assembly to the global assembly cache, reverting to local bin and use of CAS

I have been having a strange error with the deployment of a solution to MOSS 2007. On my local machine the solution gets installed and deployed nicely however when I move it to staging server it returns an error:

Error: Cannot add the specified assembly to the global assembly cache: [myassemblyname.dll].   at Microsoft.SharePoint.Administration.SPSolutionPackage.UpdateGacFile(SolutionFile file, String sourcePath, Boolean install)
   at Microsoft.SharePoint.Administration.SPSolutionPackage.UpdateFiles(String vrPath, Boolean install)
   at Microsoft.SharePoint.Administration.SPSolutionPackage.EnableWebApplication(String vrPath, Boolean globalInstall, TextWriter logWriter, Boolean force)
   at Microsoft.SharePoint.Administration.SPSolutionLanguagePack.DeploySolutionPackage(SPWebApplication webApp, Boolean globalInstall, Boolean force, String& errMsg)
   at Microsoft.SharePoint.Administration.SPSolutionLanguagePack.DeployFilesInstallFeatures(SPWebApplication webApp, Boolean globalInstallWPPackDlls, Boolean installFeatures, Boolean force, Int32 tries)
   at Microsoft.SharePoint.Administration.SPSolutionLanguagePack.DeployLocalCore(Boolean globalInstallWPPackDlls, Collection`1 webApplications, Boolean useAdminService, Boolean force)
   at Microsoft.SharePoint.Administration.SPSolutionLanguagePack.DeployLocal(Boolean globalInstallWPPackDlls, Collection`1 webApplications, Boolean force)
   at Microsoft.SharePoint.ApplicationPages.SolutionPageBase.CreateDeploymentJob(Boolean deploy, String strSelectedWeb, Boolean globalInstall, DateTime dt, Boolean localDeployment)
   at Microsoft.SharePoint.ApplicationPages.DeploySolutionPage.BtnSubmit_Click(Object sender, EventArgs e)
   at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
   at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

 

After having searched for answers and posted a question on the MSDN forum: still nothing. Seems I’m the only one having this error, at least for the time being :-(

My solution to this problem is adding the assemblies to the local bin of the application. I have read that this is the recommended approach.
However using this approach there is an important aspect to take into account: the CAS (code access security) permission set. When an assembly is deployed to the GAC it runs with Full trust. When deploying to the web application's bin directory the assembly runs with minimal trust. It is necessary to add CAS (Code Access Security) elements to the <solution> schema in order to set the right permissions.

My solutions are being deployed nicely now, it was a small challenge to find the correct security settings to implement however. I finally found some nice blog posts with a few samples and found the correct settings.

CAS itself is actually something in ASP.NET, not just SharePoint.

Some of my resources for CAS:

 

[Update 26-Aug-2007] While installing solutions with DLLs to the GAC I'm still having this problem from time to time on one single machine. My solution for the moment is rebooting the server and running the install solution script again. Luckily it's only the staging server presenting this issue so a reboot is not so much an issue.

 

Technorati tags:

Great blog post on MOSS Resource files and how to deploy

[via Michael Dukov]

If you implement multilingual or localized customizations of WSS and MOSS this post is for you: Michael Dukov wrote a nice overview of how you can use resource files (resx), how to implement them in features, in ASPX pages and even supplies some source code to deploy global resources using a feature.

Link to the article: http://dikov.blogspot.com/2007/03/sharepoint-resources-types-use-and_2163.html


Part II – Creating publishing content types

Part I: Creating site columns, publishing content types and page layout using a feature

Before going into detail on the creation of content types via features it is important to understand how Content type IDs work.
You should read the following MSDN page that explains about ContenTypes IDs and their inheritance based model: http://msdn2.microsoft.com/en-us/library/aa543822.aspx

Since this post shows how to create Publishing Content Types we need to find from which existing content type we want to base our own. I did some research on the features that are installed and activated when you use the Publishing site. In there we can see that the base content type from which we want to inherit is the “Page”. This Content Type has an ID of:

0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB0
64584E219954237AF39

So in order to create our own ID we can add two hexadecimal values, or, we can add “00” followed by a GUID. I prefer this approach as it is unique and identifies custom content types more easily.

So my content type ID can be:

0x010100C568DB52D9D0A14D9B2FDCC96666E9F20079481
30EC3DB064584E219954237AF39
00ADB88465BE2C439798977662094183BC

The bold text is the Page content type ID to which I append “00” and a new GUID.

 

Content Type Schema

Second important piece of information is the Content Type schema. I could not find any information specific to publishing content types on MSDN or the MOSS SDK. So again the solution is to use the available information together with some nosing in the publishing features installed by MOSS in the 12 hive. ContentType schema on MSDN: http://msdn2.microsoft.com/en-us/library/aa544268.aspx

 

In the following sample I’m creating two content types: a product content type and a hardware product content type. You will see that the hardware product content type inherits from the product content type by appending 00 + a new GUID to the ID.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

 

      <!-- Product base content type -->

      <ContentType ID="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007
948130EC3DB064584E219954237AF3900ADB88465BE2C43979
8977662094183BC
" Name="$Resources:contenttype_productbase_name;" Description="$Resources:contenttype_productbase_description;" Group="$Resources:group_productcontenttypes;" Sealed="FALSE" Version="0">

            <FieldRefs>

                  <FieldRef ID="{F44BFBB0-4725-4167-B976-F85F84131AA3}" Name="ProductCategory" Required="FALSE" />

                  <FieldRef ID="{EB19D87C-5DEE-4a73-85E0-506293D422D9}" Name="ProductName" Required="TRUE" />

                  <FieldRef ID="{D73843E5-0D9F-4400-BC75-1A4C2BD27900}" Name="ProductIntro" Required="TRUE" />

                  <FieldRef ID="{894635F9-1DF8-46f1-BC47-46EFF09FEF3D}" Name="ProductDescription" Required="FALSE" />

                  <FieldRef ID="{D89C9409-2A97-4a7a-81F5-7D45E7CD8D6B}" Name="LaunchDate" Required="TRUE" />

                  <FieldRef ID="{6036ECDE-521A-4dbe-94B4-40E0E4EF7029}" Name="ProductImage" Required="FALSE" />

                  <FieldRef ID="{F31DF817-D220-4449-BD6F-2F1B7C0823ED}" Name="ProductPrice" Required="TRUE" />

            </FieldRefs>

            <DocumentTemplate TargetName="/_layouts/CreatePage.aspx" />

      </ContentType>

 

 

      <ContentType ID="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3D
B064584E219954237AF3900ADB88465BE2C439798977662094183BC00B2DE
F3B02D274199BFF43C6D2F129D99
" Name="$Resources:contenttype_hardwareproduct_name;" Group="$Resources:group_productcontenttypes;" Sealed="FALSE" Version="0">

            <FieldRefs>

                  <FieldRef ID="{6A08E31A-0620-45df-BAC1-54A4D0FBFDCE}" Name="ProductManual" />

            </FieldRefs>

            <DocumentTemplate TargetName="/_layouts/CreatePage.aspx" />

      </ContentType>

     

 

</Elements>

 

Now we need to add this to the feature and install it together with what was done in part I of this series.

 

The complete feature can be downloaded here.

 

Technorati tags:

 


SharePoint Solution Installer - a MOSS 2007 tool

[via Patrick Tisseghem]

Lars Fastrup has just released a freeware SharePoint Solution Installer. The tool was developed for the Ontolica for SharePoint search engine and he decided to offer it as tool for the community.

Download the SharePoint Solution Installer.

Thanks Lars!


Part I – Creating site columns, publishing content types and page layout using a feature

Creating site columns

In this 3 part series I will explain the steps you need to follow in order to create site columns, content types and page layouts for use with a MOSS publishing site.
There is already quite some information to be found on the internet on how to create site columns and custom lists using a feature, however most part apply to team sites (WSS3 sites), not MOSS publishing sites.

Field definition schema

Site columns are created by placing <Field> elements inside an <Elements> tag. It is important to review the <Field> element definition before going any further. The complete schema definition is detailed in the WSS3 SDK which can be consulted online on the MSDN site (http://msdn2.microsoft.com/en-us/library/ms437580.aspx). On the mentioned URL you can find all the types of fields available out of the box, the required attributes, possible values and so forth.
This is very good documentation for WSS3 fields but information on extra field types for publishing site columns is not available. At least I was unable to find it in the MOSS SDK or online. My solution was to look at the feature definitions used by MOSS publishing feature available out of the box.

Most of the attributes of the <Field> element are optional. This is a sample field definition using the most common attributes:

<Field

ID="{4C67267C-B950-4cd4-8038-DEACA9EC2F74}"

Name="IntroductionText"

StaticName=" IntroductionText " SourceID="http://schemas.microsoft.com/sharepoint/v3"

Group="My publishing fields group"

DisplayName="Introduction text field"

Type="Text"

Required="FALSE"

Sealed="TRUE"

MaxLength="250"></Field>

When using other types of fields there are extra attributes that are useful.
A note about the sealed attribute: setting this to “TRUE” will ensure the field cannot be removed via the “Change column” page. However when you are creating a choice field (a dropdown, a checkbox list), and you want your users to be able to edit the list of values you need to set sealed to FALSE.

Some attributes are only used in combination with some types of fields, like for example the StorageTZ attribute, which is useful together with Type="DateTime".

When it comes to publishing field types there are some new types that you can use. As far as I could find they are not yet documented. By looking at the “PublishingResources” hidden feature I could find the following:

Field type

Description

Related attributes

Image

Publishing field for storing an image. The edit control shows the Insert picture button.

RichText="TRUE"

RichTextMode="FullHtml"

HTML

HTML editing control

RichText="TRUE" RichTextMode="FullHtml"

Link

Hyperlink control

In edit mode, allows the user to select an internal file (also external links can be allowed)

In display mode shows the clickable link to the file

RichText="TRUE" RichTextMode="FullHtml"

SummaryLinks

Field control for editing a list of links

 

There are also some extra fields that are related to the page publishing content types such as “Publishing schedule start date”. I don’t think you’d like to use these as the page content types normally already inherit these types of columns.

As a sample for this and the following posts in this series I’m creating a product page content type. My product contains 8 fields going from name and description, date, image, price.
This is the XML schema (myfields.xml):

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

<!-- _lcid="1033" _version="12.0.4017" _dal="1" -->

<!-- _LocalBinding -->

<!--

-->

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<Field ID="{F44BFBB0-4725-4167-B976-F85F84131AA3}" Name="ProductCategory" StaticName="ProductCategory" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="$Resources:column_group_products;" DisplayName="$Resources:column_productcategory_displayname;" Type="Choice" Format="Dropdown" Required="FALSE" Sealed="FALSE">

<CHOICES>

<CHOICE>$Resources:column_productcategory_choice1;</CHOICE>

<CHOICE>$Resources:column_productcategory_choice2;</CHOICE>

<CHOICE>$Resources:column_productcategory_choice3;</CHOICE>

</CHOICES>

</Field>

<Field ID="{EB19D87C-5DEE-4a73-85E0-506293D422D9}" Name="ProductName" StaticName="ProductName" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="$Resources:column_group_products;" DisplayName="$Resources:column_productname_displayname;" Type="Text" Required="TRUE" Sealed="TRUE" MaxLength="255"></Field>

<Field ID="{D73843E5-0D9F-4400-BC75-1A4C2BD27900}" Name="ProductIntro" StaticName="ProductIntro" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="$Resources:column_group_products;" DisplayName="$Resources:column_intro_displayname;" Type="Text" Description="$Resources:column_intro_description;" Required="TRUE" Sealed="TRUE" MaxLength="500" NumLines="2"></Field>

<Field ID="{894635F9-1DF8-46f1-BC47-46EFF09FEF3D}" Name="ProductDescription" StaticName="ProductDescription" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="$Resources:column_group_products;" DisplayName="$Resources:column_productdesc_displayname;" Type="HTML" Required="FALSE" Sealed="TRUE" RichText="TRUE" RichTextMode="FullHtml"></Field>

<Field ID="{D89C9409-2A97-4a7a-81F5-7D45E7CD8D6B}" Name="LaunchDate" StaticName="LaunchDate" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="$Resources:column_group_products;" DisplayName="$Resources:column_date_displayname;" Type="DateTime" Format="DateTime" Required="TRUE" Sealed="TRUE" StorageTZ="UTC"></Field>

<Field ID="{6036ECDE-521A-4dbe-94B4-40E0E4EF7029}" Name="ProductImage" StaticName="ProductImage" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="$Resources:column_group_products;" DisplayName="$Resources:column_image_displayname;" Type="Image" Required="FALSE" Sealed="TRUE" RichText="TRUE" RichTextMode="FullHtml"></Field>

<Field ID="{6A08E31A-0620-45df-BAC1-54A4D0FBFDCE}" Name="ProductManual" StaticName="ProductManual" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="$Resources:column_group_products;" DisplayName="$Resources:column_manual_displayname;" Type="Link" Required="FALSE" Sealed="TRUE" RichText="TRUE" RichTextMode="FullHtml"></Field>

<Field ID="{F31DF817-D220-4449-BD6F-2F1B7C0823ED}" Name="ProductPrice" StaticName="ProductPrice" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="$Resources:column_group_products;" DisplayName="$Resources:column_productprice_displayname;" Type="Currency" Required="TRUE" Sealed="TRUE" Decimals="2"></Field>

</Elements>

To install the field definitions via a feature I’m creating a feature.xml file that refers to the myfields.xml. In the feature file I also add a dependency to the PublishingSite feature.

A note about resources files

As you may notice in the display name and description attributes I’m referring to a resource instead of typing in the text. I recommend using resource files whenever translatable (non system name) text is used.
Living in Belgium, a country where we have three official languages I’m used to creating multi-lingual applications. Even when a first requirement does not specify a multi-lingual approach I still prefer to foresee resource files.
When creating features you can use local resource files by placing them in a sub-folder in the feature directory.
Screenshot here.

In the next post I will explain how to add a content type definition and use the fields created in this post.

Just a final note for the first post: the installation batch file I use to install a feature can be found here.


 

 


 


STSADM.EXE - custom commands for WCM, by Andrew Connell

Just a quick post about a tool I just found: the STSADM.EXE WCM Custom commands tool, developed by Andrew Connell (see his blog).

This tool lets enables some administrative actions specifically related to Web content management in Office Sharepoint Server 2007 like publishing all items in a web, generating the XML elements file for content types and site columns.

This is the link to the tool: http://www.andrewconnell.com/blog/articles/MossStsadmWcmCommands.aspx

 


Codeplex projects for SharePoint

There are already some very useful projects and toolkits available for WSS3 and MOSS 2007.
While reviewing the Codeplex site I filtered on some of the most interesting ones for me now:

And this is just to begin! There are lots more and certainly more to come.


Publishing Content types and site columns using features - specifying required fields in the XML schema

Today I came across something strange after having created site columns and content types (for publishing) using features.
Two features are used:

  • Site fields/columns definition where I specify the definition of each site column.
  • Content types: based on publishing content types to be used by page layouts. This feature refers to the fields created by my first feature.

My problem was that all required fields defined by my site columns feature were not being validated as required field after saving the page. In other words, the page was saved without error messages being shown for the required fields.
Site column definition specifies the field is required however:

<Field ID="GUID_HERE" Name="MyDateField" StaticName="MyDateField"
SourceID=http://schemas.microsoft.com/sharepoint/v3
Group="My publishing group"DisplayName="MyDateField"
Type="DateTime"
Format="DateTime"
Required="TRUE"
Sealed="TRUE"
StorageTZ="UTC"></Field>

The reason for this behavior: fields being marked as Required="True" in the fields definition feature are not automatically set as required in the content type.

<ContentType ID="ID_HERE" Name="MyContenttype" Group="Mygroup" Sealed="FALSE" Version="0">
<FieldRefs>
<FieldRef ID="{82734328-4682-43a9-A516-96C96FBBEE40}" Name="MyTextField" />
<FieldRef ID="{3843B4BD-CB7C-4339-A499-638501E0E44F}" Name="MyDateField" Required="TRUE" />
</FieldRefs>
<DocumentTemplate TargetName="/_layouts/CreatePage.aspx" />
</ContentType>

In the above sample the first field will not be validated in the page layout, even if this field has been set as required in the <Field> definition file. The second field in the content type, setting Required="TRUE" explicitly will be correctly validated.

If you create your publishing content types directly using the MOSS interface you will probably never run into the problem.
 


MOSS 2007 custom search page - javascript error

This is an error I encountered when creating a custom search page in MOSS 2007.

After creating a new custom search page and placing the Core Search Results, Search Results Paging webparts I always had a Javascript error "Object Expected", line xxx when clicking on Next page. 
The line number corresponds the href of the paging link : javascript:PostToUrl(''). My first idea is that some basic required javascript library has not been loaded.

Luckilly I found someone with a similar problem, actually a different problem with the same solution: http://www.sharepointblogs.com/joeldhall/archive/2007/01/04/17470.aspx

In Joel's solution just adding the Search Box webpart and setting it to closed in order to hide it is sufficient. Unfortunately in my case this is not. If I close the web part the error reappears.

Maybe someone else knows why this happens and has a better solution? 


Error when trying to delete a page layout in MOSS: This item cannot be deleted because it is still referenced by other pages

Today I ran into an error while creating page layouts using a feature. I made a mistake in the XML that provisions the files to install with the feature for my page layouts. My problem was an incorrect value in the attribute for the content type ID linked to my installed page layout.

After realizing my mistake and correcting it, uninstalling the feature and reinstalling it again the original incorrect page layout was still installed. This seems to be normal in SharePoint. Even when deactivating and uninstalling a page layouts feature these pages still stay in the "Master Page and Page Layout Gallery". I still have to find the right documentation on why this happens but I imagine it has to do with ghosting of the pages.

Now back to my problem. Since the incorrect page layout was still installed and giving me error messages I tried to delete it manually from the gallery. This gave me the following error message:

"This item cannot be deleted because it is still referenced by other pages"

Even if this is not the case (there was no page using this page layout), the problem is mentioned in the following KB article:

http://support.microsoft.com/?kbid=926812

The KB proposes to change the properties of the master page to Hidden. This workaround did not solve my problem since everytime I tried to access the page layout's Properties screen I got another error message due to my mistake discussed above.

There was however one workaround that solved the problem:

  1. Create a new sub-folder in the master page gallery
  2. Move the page layout to the new folder (I did this by using SharePoint Designer)
  3. In the MOSS interface, delete the complete folder by using the dropdown menu.

Yep, my page layout is finally gone from the gallery!

While my problem was specific to a page layout I think the same solution will work with master pages as well.

Technorati tags:

WCM resources - MOSS 2007

Web content management is a new feature in Sharepoint (MOSS 2007). These are my most important resources for getting information on WCM:

There are also some other tools I like using when developing WSS/MOSS, I'll post these another day.

Copyright © 2007 Katrien De Graeve.