21 September 2009

SharePoint Development Solution End-To-End

Over the next few weeks I plan on putting together an end-to-end solution that I've been working on for one of our internal clients. The goal is to demonstrate some of the things that I've learned (and continue to learn) while building a solution for SharePoint. I welcome feedback and tips as I'm sure there may be better ways to accomplish some of my goals.

The project is to build a document management system for the authoring and distribution of Information Technology Knowledge Base Articles using SharePoint and Microsoft Word. These articles will be linked to a custom in-house ticket management system. We must also move over 400 existing articles into the SharePoint site and attach the appropriate metadata.

The current system works well for simple tasks, but when assembling complex documents with screenshots, tables and reports, the current system can be limited and cumbsome. For documents that will contain screenshots or images, the author must prepare all of their screenshots or images ahead of time, upload them to the system and then create the links to those images in the current system. While this process works, the workflow is very cumbersome and takes more time than it should.

Here are the primary goals of this project:

  1. Leverage SharePoint Document Authoring, Workflow, Search and Metadata for the creation and management of Knowledge Base Articles
  2. Define and collect required metadata for KB documents to make key information available for previewing.
  3. Standardize document creation process by using a predefined template.
  4. Maintain existing documentation and update links from the work orders to the knowledge base articles.
  5. Synchronize categories between existing system and SharePoint and keep them up-to-date.
  6. Leverage SharePoint Search Web Service to find and link KB documents in SharePoint to work orders.

To create the solution, I will be using WSPBuilder to create and maintain my feature. This Codeplex project does much of the heavy lifting of preparing and deploying the solution package. I have decided to deploy a feature as the current internal work order system may eventually be used by multiple internal clients to manage their work orders. By deploying the SharePoint side of the project as a SharePoint Solution (wsp), any existing or new sites in SharePoint can be made a container for Knowledge Base Articles. I had considered just creating a site definition and adding it to SharePoint, but I would rather have the option of either creating a new site or extending an existing site to contain these items. If I had decided to do a site definition, I would only be able to create new sites and would be unable to extend the current site collection.

To start this series, I created the layout of my feature in Visual Studio 2008. In visual studio, I created a new WSPBuilder Project. This project template is installed with the WSPBuilder project from Codeplex. The new project template will create a new project with a signing key, the 12 hive root folder and a solutionid.txt file. On the 12 hive, I created the TEMPLATES and FEATURES folders. These are the folders in the 12 hive that contain all of the configuration information for SharePoint. Inside the features folder, I added my custom folder (KBRepository) that will contain the XML definition files for my custom feature.

When done, my folder stucture appears as follows:

  • Solution
    • VS Project
      • 12
        • TEMPLATE
          • FEATURES
            • KBRepository
    • KBRepository.snk
    • solutionid.txt

Inside the KBRepository folder, I added the Feature.xml file that will contain the definition of my new feature. To make authoring the XML file a little easier, locate Schemas in your Properties window and click the ellipses. Click Add and then navigate to your 12 hive/TEMPLATE/XML and click on wss.xsd. Visual Studio will now provide intellisense to help define the feature. Here is the feature definition:

<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
Creator="Software Development"
Description="Sets up this site collection to author and manage KB Articles"
Title="KB Repository"
<ElementManifest Location="KBItemFields.xml"/>
<ElementManifest Location="KBContentTypes.xml"/>

Notice I have two element manifest files. These two files will be used to create site columns and content types that will be used by other parts of my solution. The KBItemFields.xml and KBContentTypes.xml files were also created in the root of the KBRepository folder.

I opened KBItemFields.xml and added the following XML. (Remember, if you click on Schemas and associate the wss.xsd you'll get intellisense support).

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field ID="{B180626E-4DD1-44ca-9157-00639A0945DA}"
DisplayName="Reference Category ID"
Group="Category Columns"/>
<Field ID="{58AD2A67-B08C-4803-956F-82F425201D6B}"
DisplayName="Category Description"
Group="Category Columns"/>
<Field ID="{793E8479-066B-41be-B494-0D4207B8BD0A}"
DisplayName="Active Category"
Group="HICUP Category Columns"/>
<Field ID="{A4F4E2EA-80CB-4a16-ACC5-060E922EB06C}"
DisplayName="Customer Category"
Group="Category Columns"
<Field ID="{DFE30371-501F-4dd3-B11A-54C762AFEE09}"
DisplayName="Keyword List"
Group="Knowledge Base Columns"/>
<Field ID="{C486FB10-F649-476a-8606-495F900DD383}"
DisplayName="Review Needed Date"
Group="Knowledge Base Columns"/>

Now in the KBContentTypes.xml, I provided the following XML:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<!-- CATEGORY -->
<ContentType ID="0x0100aa4bb14f2f8746db941ef9b5e52b4cDF" Name="KB Category" Description="A category contained in the KB system"
Group="KB" Hidden="FALSE" Version="1">
<FieldRef ID="{B180626E-4DD1-44ca-9157-00639A0945DA}" Name="WSSAPPDEV_CategoryID" ShowInDisplayForm="TRUE" ShowInEditForm="FALSE" Required="TRUE" ShowInNewForm="FALSE" />
<FieldRef ID="{58AD2A67-B08C-4803-956F-82F425201D6B}" Name="WSSAPPDEV_CatDescription" ShowInDisplayForm="TRUE" ShowInEditForm="FALSE" Required="FALSE" ShowInNewForm="FALSE"/>
<FieldRef ID="{793E8479-066B-41be-B494-0D4207B8BD0A}" Name="WSSAPPDEV_Active" ShowInDisplayForm="TRUE" ShowInEditForm="FALSE" Required="TRUE" />
<FieldRef ID="{A4F4E2EA-80CB-4a16-ACC5-060E922EB06C}" Name="WSSAPPDEV_CustomerCat" ShowInDisplayForm="TRUE" ShowInEditForm="FALSE" Required="TRUE"/>
<ContentType ID="0x010100aa4bb14f2f8746db941ef9b5e52b4cF0" Name="IT Knowledge Base Article" Description="Knowledge Base Information Article for KB"
Group="KB" Hidden="FALSE" Version="1">
<FieldRef ID="{DFE30371-501F-4dd3-B11A-54C762AFEE09}" Name="WSSAPPDEV_Keywords" Required="TRUE" />
<FieldRef ID="{C486FB10-F649-476a-8606-495F900DD383}" Name="WSSAPPDEV_ReviewDate" Required="TRUE" />

I'm ready to deploy and test my budding solution. If you right click on the project node in your solution explorer, there is a new WSPBuilder Menu. From this menu, select Deploy and it will deploy to the SharePoint instance on the local machine.

Upon successful deployment, navigate to site and activate the feature by going to Site Actions > Site Collection Features and choosing to activate the feature. The feature has been scoped as Site, so this places it into the Site Collection Features. After activation, the new site columns and content types have been added to the root level of the site.

Congratulations, you have successfully built and deployed your first feature to SharePoint. In my next installment, I am going to create a feature receiver and programatically create some new lists to contain the categories and KB documents. I will also create a site column that performs a lookup into my category list and add the new site column to the IT Knowledge Base Article content type.

1 comment:

Chris said...

I just discovered something very helpful when declaring field types that will be used for a Document Information Panel deployed to the Content Types -- you must provide the SourceID or you will get the error "Reference to undeclared namespace prefix: 'ns1'" when attempting to create a DIP on the content type. The definition of the field type should be:

<Field ID="{DFE30371-501F-4dd3-B11A-54C762AFEE09}"
Name="WSSAPPDEV_Keywords" StaticName="WSSAPPDEV_Keywords"
DisplayName="Keyword List" Type="Text"
MaxLength="1000" Indexed="true"
LCID="1033" SourceID="http://schemas.microsoft.com/sharepoint/v3"
Group="HICUP Knowledge Base Columns"/>