MSDN Magazine > Issues and Downloads > 2006 > July >  Taking Advantage of Developer Improvements In S...
WSS 3.0 Preview
Discover Significant Developer Improvements In SharePoint Services
Ted Pattison

This article is based on a prerelease version of Windows SharePoint Services. All information herein is subject to change.
This article discusses:
  • Integration with ASP.NET 2.0 Web Parts
  • Enhancements in content storage and site configuration
  • Workflows in WSS
  • Internet-style security features
This article uses the following technologies:
WSS, Windows Server 2003
The next major release of Microsoft Office SharePoint Server (MOSS), including Windows® SharePoint® Services (WSS) version 3.O, is fast approaching release. As with previous versions, WSS supplies out-of-the-box collaboration features that make it simple for users to create and design Web sites with shared elements such as calendars, contacts lists, and document libraries. But WSS is far more than a collaboration tool for end users. It is a full-fledged development platform that adds tremendous value to ASP.NET.
WSS 3.0 is an add-on for Windows Server™ 2003. At its core, WSS acts as a scalable site-provisioning engine, easing the process of creating and managing hundreds or thousands of Web sites and making them accessible to tens of thousands of users. WSS scalability is achieved by using an architecture designed with a Web-farm environment in mind. This architecture is based on stateless front-end Web servers that rely on SQL Server™ for storing content and other site-related data.
The added value WSS brings to the ASP.NET 2.0 development platform results from its extensibility model, which facilitates provisioning and storage for pages, lists, and document libraries. The provisioning can be driven through either custom code or user actions in the browser-based UI. Behind the scenes, WSS automatically works out how and where to store the content, and it also supplies the UI elements that let users add, view, and modify content.
I’m going to concentrate on the most significant developer enhancements to version 3, and on the accompanying changes in terminology. For more information, see "SharePoint: Use Windows SharePoint Services as a Platform for Building Collaborative Applications" in the July 2004 issue of MSDN®Magazine.
Keep in mind that research and code samples for this article are based on the Beta 1 release of WSS. It’s possible that some of the terms and code might change in the released version.

Integration with ASP.NET 2.0
WSS 3.0 provisioning starts with an IIS Web site. Before you can create your first WSS site, you need to run an administrative procedure that extends the WSS functionality to one or more IIS Web sites. With WSS 2.0, the term "virtual server" was used to describe an IIS Web site extended with SharePoint functionality. To avoid confusion with another Microsoft product of the same name, the WSS 3.0 documentation now refers to an IIS Web site extended with WSS functionality as a Web application.
WSS 2.0 was integrated with IIS 6.0 and ASP.NET 1.1 using an ISAPI filter DLL, which resulted in IIS routing requests to WSS before ASP.NET. That routing could be problematic in certain situations because WSS takes control of an incoming HTTP request before it has had a chance to be properly initialized with ASP.NET context.
But WSS integration with ASP.NET has been completely redesigned in version 3. First, WSS 3.0 is built on ASP.NET 2.0, which provides significant enhancements over ASP.NET 1.1. Furthermore, the routing infrastructure was improved by removing the ISAPI filter and by adding an HttpModule and an HttpHandler that are registered with ASP.NET using standard web.config entries. This means that incoming HTTP requests always enter the ASP.NET runtime environment and are fully initialized with ASP.NET context before they are forwarded to the code that carries out WSS-specific processing.
When you extend an IIS Web site to become a Web application, WSS 3.0 adds a wildcard application map to the IIS metabase. This map routes all incoming HTTP requests to the ASP.NET runtime regardless of file type (.pdf, .doc, .docx, and so on). ASP.NET then forwards the request to WSS for processing.
The new architecture also deals with shortcomings related to how .aspx pages are parsed and compiled. The .aspx page parser used by ASP.NET 1.1 works only with pages that reside on the local file system. But WSS architecture relies on storing .aspx pages in a SQL Server database so it couldn’t take advantage of the ASP.NET 1.1 page parser. And, unfortunately, the SharePoint parser developed in its place does not support many of the cooler features offered by the ASP.NET page parser.
But ASP.NET 2.0 introduced a new pluggable component type known as a virtual path provider. The idea is that a developer can write a custom component that retrieves .aspx pages (or any other content that ASP.NET processes) from any location, including a database such as SQL Server. Once a custom virtual path provider retrieves an .aspx page, it can then hand the page off to ASP.NET to conduct the required parsing and compilation. A separate component, PageParserFilter, lets SharePoint control how pages are parsed and compiled and what executes on those pages.
WSS 3.0 includes its own virtual path provider named SPVirtualPathProvider, as illustrated in Figure 1. As you can see, SPVirtualPathProvider is able to retrieve .aspx pages from SQL Server and then hand them off to the .aspx parser that is supplied by ASP.NET 2.0. As a result, WSS 3.0 does not suffer from a reduced feature set with respect to page parsing as did the previous version of WSS.
Figure 1 Custom Virtual Path Provider and ASP.NET 2.0 

Page Templates
The terms ghosting and unghosting are often used in conjunction with the .aspx pages of a WSS 2.0 site. Page ghosting lets a front-end Web server store an .aspx page template on its local file system and share that template across many different sites. Page ghosting offers performance benefits because WSS can serve up pages for thousands of sites using a page template stored on the local file system and loaded into memory just once.
WSS 2.0 supported user modifications to the page template using tools such as Microsoft® Office FrontPage® 2003. When a user modifies a page template and saves the changes, a customized version of the page is stored in SQL Server for that particular site. This is often referred to as unghosting a page.
WSS 3.0 still supports page templates that live on the Web server as well as customized versions that are stored in SQL Server. However, the documentation no longer uses the terms ghosting and unghosting. Now the term "uncustomized page" describes a page template used directly from the local file system of the Web server, while "customized page" is used when talking about a modified version of the page template that has been written to the content database for a particular site.
Microsoft Office FrontPage 2003 has been renamed Office SharePoint Designer 2007, but its target audience remains users rather than developers. Still, it’s a handy tool for WSS developers. SharePoint Designer provides both a code editor and a WYSIWYG designer for customizing .aspx and .master pages within WSS sites, and you can create new pages within a site that has no corresponding page template on the Web server. You can also create lists and document libraries and there’s even a new wizard for creating custom workflows in a WSS site. (I’ll discuss this in more depth later.)

Working with Master Pages
One of the most tedious aspects of customizing and branding sites in WSS 2.0 involved creating a consistent appearance across pages, due to the fact that ASP.NET 1.1 didn’t provide any suitable page templating techniques. As a result, many developers and designers resorted to copying HTML layouts and pasting them from page to page. As you can imagine, this makes it very hard to customize and maintain a site whose layout requirements differ from the standard WSS site.
A remedy appeared in the form of a powerful page templating feature known as Master Pages, introduced with ASP.NET 2.0. A Master Page is a template that allows you to define a standard page layout for an entire site with elements such as a banner, navigation controls, and other menus. The pages that link to a Master Page are known as content pages.
The key concept is that each content page links to the Master Page to acquire the shared layout and then extends the Master Page by inserting customized content in named placeholders. For more information about how Master Pages work in ASP.NET, see Fritz Onion’s article "Master Pages: Master Your Site Design with Visual Inheritance and Page Templates" in the June 2004 issue of MSDN Magazine.
WSS 3.0 was designed from the ground up to embrace the Master Page infrastructure of ASP.NET 2.0. Every version 3 site is provisioned with a special catalog known as the Master Page gallery that contains a page named default.master. This page defines a common layout for every site’s home page (default.aspx) as well as all the standard WSS form pages associated with lists and document libraries (AllItems.aspx and NewItem.aspx, for example). The Master Page layout includes standard menus and navigation controls. Figure 2 shows an example page based on the standard layout defined by default.master.
Figure 2 Standard Layout of Pages Defined by default.master 
The default.master definition includes a number of named placeholders such as PlaceHolderPageTitle, PlaceHolderMain, and PlaceHolderLeftNavigation, making it relatively simple to create a new custom content page with the same layout as other pages in a site. Take a look at the simplicity of the content page definition:
  <%@ Page language="VB" MasterPageFile="~masterurl/ 
    default.master" %>
  <asp:Content ContentPlaceHolderId="PlaceHolderMain"
    runat="server">
    <h3>Welcome to customization with Windows      SharePoint Services 3</h3>
    This is so much easier than it was in version 2!
                     </asp:Content>
The content page definition does nothing beyond placing a minimal fragment of HTML content inside PlaceHolderMain, but it produces the typical page layout with site icons, menus, and navigation bars as shown in Figure 3. Once you learn how to use the standard set of placeholders defined in default.master, you can easily replace WSS elements like menus and navigation bars with your own ASP.NET controls. This can be done for pages at the scope of a site or a site collection.
Figure 3 Custom Content Page from a Master Page 
Master Pages and content pages are stored and loaded like the page templates and page customization discussed earlier. There are page templates defined for the Master Page as well as for content pages that reside on the local file system of the front-end Web server. Each site initially uses uncustomized (ghosted) versions of the Master Page template and content page templates. When a user customizes and saves one of these pages for a particular site using a tool such as SharePoint Designer, a customized (unghosted) version is saved into the SQL Server database.
You can customize the Master Page for a site if you like, leaving the content pages uncustomized. Or you can customize one or more content pages while leaving the Master Page uncustomized. And you can undo any changes; both WSS and SharePoint Designer provide simple menu commands to discard customization changes from the SQL Server database and revert back to the original page template.
As you might have noticed, the content page that was shown previously links to the Master Page using a special syntax in the form of ~masterurl/default.master. This is a tokenized reference to a Master Page that can be changed programmatically on a site-wide basis. To do this, you acquire an SPWeb reference to the current site and then update the MasterUrl property (see Figure 4).
Imports System.Windows.Forms
Imports Microsoft.SharePoint

Public Partial Class frmMain : Inherits Form
    Sub cmdSetMasterUrl_Click( _
            ByVal sender As Object, ByVal e As EventArgs)

        Using SiteCollection As New SPSite("http://localhost")
            Using TopLevelSite As SPWeb = SiteCollection.OpenWeb()
                TopLevelSite.MasterUrl = txtMasterUrl.Text
                TopLevelSite.Update()
            End Using
        End Using

    End Sub
End Class
Note that each site has its own Master Page gallery with a default.master and its own MasterUrl property. That means all the sites inside a site collection do not automatically use the same Master Page. However, with the use of recursion, it’s pretty easy to write some code against the WSS 3.0 object model to synchronize a top-level site and all the child sites in a site collection to use the same Master Page, as shown in Figure 5.
Sub cmdSynchronizeChildren_Click( _
        ByVal sender As Object, ByVal e As EventArgs)

    Using SiteCollection As New SPSite("http://localhost")
        Using TopLevelSite As SPWeb = SiteCollection.OpenWeb()
            UpdateMasterUrlRecursive(TopLevelSite, txtMasterUrl.Text)
        End Using
    End Using

End Sub

Sub UpdateMasterUrlRecursive(ByVal site As SPWeb, ByVal Url As String)
    site.MasterUrl = Url
    site.Update()
    For Each child As SPWeb In site.Webs
        Using child
            UpdateMasterUrlRecursive(child, Url)
        End Using
    Next
End Sub
Another useful dynamic token for Master Pages takes the form of ~masterurl/custom.master. This dynamic token works in conjunction with the CustomMasterUrl property of a site and provides a secondary target Master Page that can be redirected programmatically. There are also two static Master Page tokens which start with either ~site or ~sitecollection. These static tokens allow you to hardcode a relative path to a Master Page from either the root of the current site or the root of current site collection.

Web Parts in WSS
One of the most popular ways for developers to extend WSS 2.0 sites was to create custom Web Parts. Web Parts are great because they add the extra dimensions of user customization and personalization. Largely due to the popularity of Web Parts in WSS 2.0, Microsoft decided to add support for a new Web Part infrastructure for ASP.NET 2.0 that is similar yet distinct from the Web Part infrastructure in WSS.
Consequently, there are now two different Web Part styles. The older WSS-style Web Parts have a dependency on Microsoft.SharePoint.dll and must inherit from the WebPart base class in the Microsoft.SharePoint.WebPartPages namespace. The newer ASP.NET-style Web Parts have a dependency on System.Web.dll and must inherit from a different base class named WebPart in the System.Web.UI.WebControls.WebParts namespace.
It was an important design goal for WSS 3.0 to run both the WSS-style Web Parts and the ASP.NET-style Web Parts. This goal was accomplished by building WSS 3.0 support for Web Parts on top of the ASP.NET Web Part infrastructure and then changing the Microsoft.SharePoint.dll so that WSS-style Web Parts written for the WSS 2.0 environment would be compatible with the version 3 runtime environment.
To run Web Parts in an ASP.NET 2.0 application, you must create an .aspx page that contains exactly one instance of the WebPartManager control and one or more WebPartZone controls. The WebPartManager is responsible for serializing Web Part-related data as well as storing and retrieving it from the tables in the ASP.NET services database.
The .aspx page serving as a Web Part Page can contain editor parts that allow users to customize and personalize persistent Web Part properties. Web Part Pages can also contain catalog parts that let users add new Web Parts into zones. WSS 3.0 does the work to add the catalog and editor parts for you, so a Web page designer does not need to do so explicitly. (For more background information about how the ASP.NET 2.0 Web Part infrastructure works, read the article "ASP.NET 2.0: Personalize Your Portal with User Controls and Custom Web Parts".
The WSS 3.0 Web Part infrastructure is built on top of a control named SPWebPartManager that is derived from the ASP.NET 2.0 WebPartManager control. The SPWebPartManager control overrides the standard behavior of the WebPartManager control to persist Web Part data inside the WSS content database instead of in the ASP.NET services database. In most cases, you don’t have to worry about dealing directly with the SPWebPartManager control because the one and only required instance is already defined in default.master. When you create a content page that links to default.master, the SPWebPartManager control is already there.
The other controls that appear on a typical WSS 3.0 Web Part Page are shown in Figure 6. Note that Web Part zones for a Web Part Page in WSS 3.0 should be created using the WebPartZone control defined inside Microsoft.SharePoint.WebPartPages namespace, not using the standard WebPartZone control from ASP.NET 2.0.
Figure 6 Controls in a Web Part Page 
Instances of the WebPartZone control are usually defined in content pages. Figure 7 shows a simple example of creating a content page designed to act as Web Part Page in a WSS 3.0 site. As you can see, this .aspx file links to default.master just like the earlier example. However, it also explicitly inherits from the WebPartPage base class and adds two WebPartZone controls into PlaceHolderMain.
<%@ Assembly Name="[Fully-qualified name for 
    Microsoft.SharePoint.dll]" %>
<%@ Page language="VB" MasterPageFile="~masterurl/default.master"    
    Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage" %>
<%@ Register Tagprefix="WebPartPages" 
    Namespace="Microsoft.SharePoint.WebPartPages"
    Assembly="[Fully-qualified name for Microsoft.SharePoint]"  %>

<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">
  <h3>My Custom Web Part Page</h3>
  <table border="5" cellpadding="5" cellspacing="0">
    <tr>
      <td valign="top">
        <WebPartPages:WebPartZone runat="server" ID="Left" 
                                  Title="Left Zone" />
      </td>
      <td valign="top">
        <WebPartPages:WebPartZone runat="server" ID="Right" 
                                  Title="Right Zone" />
      </td>
    </tr>
  </table>
</asp:Content>
When you create a Web Part Page for a standard ASP.NET 2.0 application, you need to add logic that interacts with the WebPartManager control to manage the Web Part display mode, and generally you also need to explicitly add editor parts and catalog parts to the page along with the HTML layout to accommodate them. Fortunately, you don’t have to do these things when creating content pages for a WSS 3.0 site. Instead, you inherit from the WebPartPage class that’s defined inside the Microsoft.SharePoint.WebPartPages namespace and let it do all this work for you behind the scenes.

Developing Custom Web Parts
The preferred approach to creating Web Parts for WSS 3.0 sites is to create ASP.NET-style Web Parts. At a minimum this involves creating a class that inherits from the WebPart base class defined in the System.Web.UI.WebControls.WebParts namespace and overriding the RenderContents method. If you want to add persistent Web Part properties, you use the same technique that is used in ASP.NET.
The Web Part definition shown in Figure 8 has no dependencies on Microsoft.SharePoint.dll so it can be used in either a standard ASP.NET application or a WSS 3.0 site. In many cases, though, you’ll want to add a reference to Microsoft.SharePoint.dll so that the code behind your Web Parts can program against the WSS 3.0 object model as well.
Imports System
Imports System.Web.UI
Imports System.Web.UI.WebControls.WebParts

Public Class SimpleWebPart : Inherits WebPart

    Protected _ZipCode As String

    <Personalizable(), _
     WebBrowsable(true), _
     WebDisplayName("Zip Code"), _
     WebDescription("used to track user zip code")> _
    Public Property ZipCode() As String
        Get
            Return _ZipCode
        End Get
        Set(ByVal value As String)
            _ZipCode = value
        End Set
    End Property

    Protected Overrides Sub RenderContents( _
            ByVal writer As HtmlTextWriter)
        writer.Write("You live at " & _ZipCode)
    End Sub
End Class
WSS 3.0 was also designed to support Web Parts created for the version 2 environment. These older-style WSS Web Parts inherit from the WebPart base class in the Microsoft.SharePoint.dll that is defined inside Microsoft.SharePoint.WebPartPages namespace.
The WebPart class in the older version of Microsoft.SharePoint.dll was designed to inherit from the ASP.NET Control class, as shown in Figure 9. However, you can also see that the WebPart class in the new version of Microsoft.SharePoint.dll has been modified to inherit from the ASP.NET Web Part class instead. This technique of changing a base class in a later version of an assembly is known as rebasing. The rebasing of the WebPart base class in Microsoft.SharePoint.dll is one of the keys to supporting older-style Web parts in a WSS 3.0 environment.
Figure 9 The Rebased WebPart Class 
If you look at the standard web.config file for a WSS 3.0 Web application, you’ll see that it contains configuration elements to redirect references from the older version of Microsoft.SharePoint.dll to the new one. This redirection, in combination with the rebasing of the Web Part base class, allows Web Part DLLs written for the version 2 environment to run inside the version 3 environment without any recompilation.
If you decide to convert a version 2 Web Part project over to Visual Studio® 2005, you can continue to evolve your code using the same style you’ve used in the past and things will still work. However, you have another option as well once you’ve moved to Visual Studio 2005 and switched the old project reference to Microsoft.SharePoint.dll over to the new WSS 3.0 version. Since the ASP.NET WebPart base class is now a part of the inheritance hierarchy, you can change some aspects of your WSS-style Web Part class as if it were an ASP.NET-style Web Part. This is known as a hybrid Web Part.

Enhancements in Content Storage
One problem developers had with WSS 2.0 was that several valuable features supported with document libraries were not supported with lists. For example, document libraries supported versioning and events, but lists did not. With WSS 3.0, lists support many of the same features as document libraries including versioning, events, and folders. There are also some new features supported by both lists and document libraries, such as exposing data through automatic RSS feeds.
WSS 3.0 introduces a new column-indexing feature to alleviate some performance problems with document libraries and lists that existed in WSS 2.0. From a list settings page or a document library settings page you can add an index to any column. This does not actually create a physical index in SQL Server. Instead, it creates a table with the integer ID of the list item or document and the value of the indexed column. WSS then uses this table to improve the performance of return data from views, especially when you use a view with a filter based on the indexed column.
Many developers wanted to be able to work with WSS fields at a lower level to obtain more control over field rendering and validation. In response, WSS 3.0 adds new extensible field types. You can create an extensible field type by writing a class in C# or Visual Basic® that inherits from one of the built-in SharePoint field types such as SPFieldText and SPFieldNumber. An extensible field type can also utilize an ASP.NET user control that contains your favorite Web controls, letting you use the same techniques for control initialization and validation you’ve used in ASP.NET applications.
Another nice innovation in WSS 3.0 is custom site columns. A site column is a reusable definition that can be applied across multiple lists. It defines the name for a column, its underlying field type, and other characteristics such as the default value, formatting, and validation. Once you’ve defined a site column, you can then use it as you define the structure of your user-defined lists. An obvious advantage is that you can update the site column in a single place and have that update affect all the lists where the site column has been used. A site column is defined within the scope of a single site, yet it is visible to all child sites below. You can create a site column that is usable across an entire site collection by defining it inside the top-level site.
Site columns give you the ability to perform field lookups across sites, something you couldn’t accomplish in previous versions of SharePoint without writing custom code. For example, you can create a site column in a top-level site that performs a look up on a list in the same site. Then you can create other lists within child sites that use this site column to perform lookups on the list in the top-level site. Imagine you want to store several different types of documents in the same document library. For example, suppose you need to store customer presentations, proposals, and reports and you want each of these document types to have its own unique set of custom columns and its own unique event handlers. In WSS 2.0, you could only add extra columns and event handlers to the document library itself, which always affects every document in that document library. Furthermore, a document library could have only one associated document template.
WSS 3.0 introduces a powerful new storage mechanism called content types to solve this problem. A content type is a flexible and reusable WSS type that defines the shape and behavior for an item in a list or a document in a document library. For example, you can create a content type for a customer presentation document with a unique set of columns, an event handler, and its own document template. You can create a second content type for a customer proposal document with a different set of columns, a workflow, and a different document template. Then you can create a new document library and configure it to support both of these content types. This is a significant enhancement because it lets you deal with heterogeneous types of content in lists and document libraries.

Event Handlers
Events in WSS 2.0 supported document libraries but not lists. Moreover, version 2 supported only asynchronous events that fired after a user action had been committed to the SQL Server database. There was no way for the developer to cancel a user’s action inside an event handler.
WSS 3.0 improves event handling by retaining support for the asynchronous events that existed in version 2 and adding support for synchronous events that let you cancel user actions. For example, you can stop a user from deleting a document once it has been approved or from creating an order with an order date in the future. And events are supported on list items as well as on documents in a document library.
You create an event handler by writing a custom class that inherits from one of the WSS receiver classes and overriding methods to handle events. For example, to handle update events for items in a list, you’d create a class that inherits from the SPItemEventReceiver class and override the ItemUpdating method as shown in Figure 10.
Imports System
Imports Microsoft.SharePoint

Public Class MyReceiver : Inherits SPItemEventReceiver
    Public Overrides Sub ItemUpdating( _
            ByVal properties As SPItemEventProperties)

        Using web As SPWeb = properties.OpenWeb()
            Dim ListId As Guid = properties.ListId
            Dim ListItemId As Integer = properties.ListItemId
            Dim Orders As SPListItem = _
                web.Lists(ListId).GetItemById(ListItemId)
            Dim OrderDate As DateTime = _
                Convert.ToDateTime(Orders(&quot;OrderDate&quot;))
            If OrderDate.CompareTo(DateTime.Today) &gt; 0 Then
                properties.ErrorMessage = _
                    &quot;You cannot enter orders for future days.&quot;
                properties.Cancel = true
            End If
        End Using

    End Sub
End Class
You can bind the event handler to a particular list or document library by either writing code against the object model or defining an event receiver in a WSS feature. For example, you can bind this event receiver to a list using code similar to this:
Dim list As SPList = web.Lists("Orders")
list.EventReceivers.Add(SPEventReceiverType.ItemAdding, _
    "[Fully-qualified Assembly name]", "Litware.MyReceiver")
WSS receiver classes use a naming convention for overridable methods that differentiates between synchronous and asynchronous events. For example, ItemUpdating is a cancelable, synchronous event that fires before the change is made to the content database. These synchronous events provide a great way to validate column values, as the event handler in Figure 10 shows.
There is a complementary asynchronous event named ItemUpdated that occurs after a change has been written to the content database. Unlike synchronous events, asynchronous events do not support canceling user actions. Instead they provide the means to perform a required operation after a change has been made to a document or list item, such as assigning the value of a calculated column or sending an e-mail notification.
In addition to supporting events on list items and documents, WSS 3.0 supports other new event types such as list events that fire when someone changes a list definition. For example, you can cancel the user’s action whenever someone tries to remove or rename a column in one of your custom lists. There are also events that fire whenever someone deletes or moves a site or an entire site collection.

Workflows in WSS
Workflow applications have been getting quite a bit of attention inside Microsoft lately. The WinFX® runtime components, to be released in concert with Windows Vista™, add a complete infrastructure—Windows Workflow Foundation—for building workflow-style applications. The workflow infrastructure includes an engine, pluggable components to persist workflow state, and a Visual Studio designer that makes it easy to create custom workflows by dragging and dropping components known as activities onto a workflow design surface.
WSS 3.0 builds on top of Windows Workflow Foundation to provide a structure for attaching business logic to list items and documents. It extends the basic workflow model by associating a task list and a history list with each workflow, adding a degree of responsibility and accountability to workflows that are human-oriented, such as a path for reviewing or approving a document.
Both WSS and MOSS 2007 ship with workflows that are installed and ready to use. WSS 3.0 includes some simple routing workflows for actions such as moderation and approval. MOSS 2007 supplies more complex workflows that support features such as the Web content management approval process.
Creating custom workflows represents an obvious extensibility point for developers building business solutions with WSS and MOSS 2007. In addition to the standard support of the Visual Studio extensions for Windows Workflow Foundation, there are plans to ship a WSS-specific workflow SDK and a starter kit that includes Visual Studio project templates for creating custom workflows for WSS sites.
SharePoint Designer also provides support for creating custom workflows in WSS 3.0 sites. This is really targeted at the power user as much or more than developers because it provides a means to step through a wizard and attach business logic to list items and documents in a production site.

Site Definitions, Features, and Solutions
Developers who have used WSS 2.0 as a platform to build business solutions have found that working with low-level site definitions provides the greatest amount of control and reusability. A site definition is a directory on the front-end Web server containing XML files and .aspx page templates that define a blueprint for the site, including list schemas and page layouts. The XML-based language that is used inside many site definition files is called Collaborative Application Markup Language (CAML).
However, there are some issues with this strategy in version 2. First, the XML files inside version 2 site definitions were poorly factored, making them unwieldy and hard to work with. Second, there was no support for evolving a site definition once it had been used to create sites. That means there wasn’t a supported technique involving site definitions that could be used to add functionality to an existing WSS 2.0 site. Third, site definitions and the custom assemblies they depend on created deployment issues because the files had to be pushed out to each front-end Web server in a farm without any assistance from the WSS infrastructure. Finally, WSS 2.0 provided no means to localize a site definition, a somewhat frustrating situation for companies wanting to internationalize their business solutions.
The first significant WSS 3.0 enhancement in this area is the introduction of features. A feature is like a site definition: a directory containing CAML-based XML files and page templates. But features offer a much more modular approach because you don’t need to define the entire blueprint for a site. Instead, a simple feature can define a single site element such as a custom list definition or menu commands to be displayed in one of the standard WSS menus.
Happily, features can be activated on an existing site. For example, you can create a feature that defines a custom list type, an instance of that list type, and an event handler or workflow on that list instance. Once the feature has been installed, it can be activated in any site within a farm and you can activate it through the WSS user interface, from the command line, or through custom code written against the WSS object model. Once the feature has been activated, the site will include your new custom list and any behavior you want to attach to it.
Features also make developing site definitions simpler. In WSS 2.0, each list definition had to be specified inside the context of a site definition. In version 3 every list definition can be factored out into its own feature. Site definitions are now easier to create as they can be composed using feature references. This is the approach taken with all the list types that ship as part of WSS collaboration services.
WSS 3.0 introduces a new deployment mechanism called a solution that is similar to Web Part packages in the sense that it is an aggregate .cab file containing XML instructions and files that need to be deployed on each front-end Web server. However, solutions go beyond Web Part packages to support the deployment of features, site definitions, and related assemblies used for event handlers and workflows.
WSS 3.0 support for solutions also assists in pushing deployment files to each Web server in a farm. An administrator adds a solution to a WSS farm, which copies the solution .cab file into the configuration database. Next, the administrator runs a command to deploy the solution, at which time WSS starts a timer job to push the solution .cab file out to each Web server and install it.
A very welcome change for WSS developers is the new support for localization. This functionality has been built on top of the localization infrastructure of ASP.NET 2.0, and it’s now possible (and recommended) to create site definitions and features in a language-neutral fashion and to maintain string literals in .resx files. Within the XML files and .aspx page template files of a feature or site definition you can acquire the value for a named string that has been localized into a .resx file using standard ASP.NET syntax.
<%$Resources:Litware,MyString%>

Internet-Style Security
Authentication in WSS 2.0 was based on Windows accounts and their associated Security IDs (SIDs). In a practical sense this meant that WSS 2.0 was tightly coupled with Active Directory® when used in anything but the smallest deployments. This dependency wasn’t a problem for companies that deployed Active Directory when they started using WSS 2.0 and SharePoint Portal Server 2003 for building intranet-based solutions. But for companies building extranet-based solutions, it was far more challenging. The tight coupling of WSS to Active Directory forced companies to create and maintain domain accounts for non-company users such as venders and customers.
All this changes with WSS 3.0 because authentication has been redesigned on top of the new authentication provider infrastructure introduced with ASP.NET 2.0. If you don’t want to maintain user accounts for WSS and MOSS 2007 sites inside Active Directory, you simply build or acquire an ASP.NET authentication provider that’s been designed to store and manage user accounts in a different identity repository.
For example, ASP.NET 2.0 ships with the forms authentication provider that allows you to maintain user accounts inside a SQL Server database. This authentication provider can be configured for use in a WSS site. With little effort, you can put a WSS site on the Internet that allows unknown users to register themselves as members. ASP.NET 2.0 provides convenient support for creating and maintaining user accounts and even allows users to change and reset their passwords.

Conclusion
I’ve covered many of the major advancements to WSS 3.0 targeted at developers, and you’ll discover even more once you begin to dig in and work with the product. It should be clear already that the WSS team has done a nice job listening to developer feedback about the previous version and responding with some significant new features.

Ted Pattison is an author and trainer who delivers hands-on training through his company, the Ted Pattison Group. Ted is currently researching and writing a new book focusing on Windows SharePoint Services 3.0 and Office 12 server technology.

Page view tracker