Category Archives: Object Model

SharePoint Associating a Workflow to a list

Continuing from my last post, one thing that you also may want to do when programmatically creating a list is associating a workflow with a given configuration (e.g. Approval workflow when a new item is created in a document library).
In the SharePoint interface we can do this association very easily but if you want to do it using the object model there are a few steps that you should have into consideration.

First what we need to create is a SPWorkflowAssociation more specifically SPWorkflowAssociation.CreateListAssociation. For this we need to give information like:

  • Workflow template – Template to use for the workflow (e.g. Approval);
  • Workflow Title – Name of the workflow;
  • Workflow task list – Name of the workflow task list (should be based on the Tasks list template);
  • Workflow history list – Name of the workflow history list (should be based on the Workflow History list template).

After creating the SPWorkflowAssociation we can set general workflow parameters that are nothing more than configurations available in all workflow templates:

  • AllowManual – Allow manual start of the workflow;
  • AutoStartCreate – Auto start the workflow on item creation;
  • AutoStartChange – Auto start the workflow on item change;
  • AssociationData – Association data to be passed to the workflow instance.

The key parameter here is the AssociationData that contains workflow template specific configurations to be passed to the corresponding workflow instances. For example referring to the out-of-box Approval workflow, its association data is something like this (in XML because the Approval workflow uses an InfoPath form for its configuration page):

<my:myFields xml:lang="en-us" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                         xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD">

    <my:Reviewers>
        <my:Person>
            <my:DisplayName>Administrator</my:DisplayName>
            <my:AccountId>Administrator</my:AccountId>
            <my:AccountType>User</my:AccountType>
        </my:Person>
    </my:Reviewers>

    <my:CC></my:CC>
    <my:DueDate xsi:nil="true"></my:DueDate>
    <my:Description xsi:nil="true"></my:Description>
    <my:Title></my:Title>
    <my:DefaultTaskType>1</my:DefaultTaskType>
    <my:CreateTasksInSerial>true</my:CreateTasksInSerial>
    <my:AllowDelegation>false</my:AllowDelegation>
    <my:AllowChangeRequests>true</my:AllowChangeRequests>
    <my:StopOnAnyReject xsi:nil="true"></my:StopOnAnyReject>
    <my:WantedTasks xsi:nil="true"></my:WantedTasks>
    <my:SetMetadataOnSuccess>false</my:SetMetadataOnSuccess>
    <my:MetadataSuccessField></my:MetadataSuccessField>
    <my:MetadataSuccessValue></my:MetadataSuccessValue>
    <my:ApproveWhenComplete>false</my:ApproveWhenComplete>
    <my:TimePerTaskVal xsi:nil="true"></my:TimePerTaskVal>
    <my:TimePerTaskType xsi:nil="true"></my:TimePerTaskType>
    <my:Voting>false</my:Voting>
    <my:MetadataTriggerField></my:MetadataTriggerField>
    <my:MetadataTriggerValue></my:MetadataTriggerValue>
    <my:InitLock>true</my:InitLock>
    <my:MetadataStop>false</my:MetadataStop>
    <my:ItemChangeStop>false</my:ItemChangeStop>
    <my:GroupTasks>true</my:GroupTasks>
</my:myFields> 

As you can see this association data contains the rest of the configuration parameters regarding the workflow template and in the case of the Approval workflow it contains something as important as the Approvers list (Reviewers).

With this you have all the information that is needed to correctly configure and associate an workflow to a list. Just don’t forget in the end to do something like SPList.AddWorkflowAssociation(SPWorkflowAssociation).

I leave you here an example method to accomplish what was described.

public SPWorkflowAssociation AddListWorkflowAssociation(SPWeb parentWeb, SPList parentList, String title, String workflowTemplateName, String workflowTaskListName, String workflowHistoryListName,Boolean workflowAllowManualStart, Boolean workflowAutoStartOnCreate, Boolean workflowAutoStartOnChange, String workflowAssociationData)
{
    // Search for workflow template in site
    foreach (SPWorkflowTemplate workflowTemplate in parentWeb.WorkflowTemplates)
    {
        if (workflowTemplate.Name == workflowTemplateName)
        { // Found

          // Check is task and history lists already exist
          SPList taskList;
          SPList historyList;
          try
          {
              taskList = parentWeb.Lists[workflowTaskListName];
          }
          catch (System.ArgumentException)
          { // Does not exist in site. Add
            taskList = SPHelper.AddList(parentWeb, workflowTaskListName, "Task list for workflow.", "Tasks", false);
          }

          try
          {
              historyList = parentWeb.Lists[workflowHistoryListName];
          }
          catch (System.ArgumentException)
          { // Does not exist in site. Add
            historyList = SPHelper.AddList(parentWeb, workflowHistoryListName, "History list for workflow.", "Workflow History", false);
          }

          // Create workflow list association
          SPWorkflowAssociation workflowAssociation = SPWorkflowAssociation.CreateListAssociation(workflowTemplate, title, taskList, historyList);

          // Set workflow parameters
          workflowAssociation.AllowManual = workflowAllowManualStart;
          workflowAssociation.AutoStartCreate = workflowAutoStartOnCreate;
          workflowAssociation.AutoStartChange = workflowAutoStartOnChange;
          workflowAssociation.AssociationData = workflowAssociationData;

          // Add workflow to list
          workflowAssociation = parentList.AddWorkflowAssociation(workflowAssociation);
          workflowAssociation.Enabled = true;

          // Return workflow object
          return workflowAssociation;
       }
    }

    // Error if reach here
    return null;

}
 

SharePoint 2007 basics – Add a Folder

Folders can be added under a list or under another
folder and the way of adding in each case is very similar. Below another
example of sample functions.

 
public SPFolder AddFolder(SPList parentList, String title)
{
    // Enable
folder creation on the list
    parentList.EnableFolderCreation
= true; 

    // Add folder
    SPListItem
listItem = parentList.Folders.Add("", SPFileSystemObjectType.Folder);
    listItem["Name"]
= title;

   // Update
   listItem.Update();

   // Return
   return
listItem.Folder;
}

public SPFolder
AddFolder(SPFolder folder, String title)
{
    // Add
    SPFolder
newFolder = folder.SubFolders.Add(title); 

    // Return
    return
newFolder;
}

 

 

SharePoint 2007 basics – Add a List

Adding a list is done very much in the same way as
a web. You just have to pay attention to were you should get your list template
from, because depending if it is a native or a custom list template the place where
to get it is different (
SPWeb.ListTemplates vs SPSite.GetCustomListTemplates). Of course that a list can only be added to a web.

So a function to add a list could be like the one
below.

public
SPList AddList(SPWeb parentWeb, String title, String description, String
listTemplate, Boolean onQuickLaunch)
{
    // Get list template object
    SPListTemplate listTemplateSP = null; 

    // Try out-of-box list templates first (Not be best way of doing this)
    try
    {
        listTemplateSP =
parentWeb.ListTemplates[listTemplate];
    }
    catch (System.ArgumentException)
    { // Try custom site templates
        SPListTemplateCollection customListTemplateCollection
= parentWeb.Site.GetCustomListTemplates(parentWeb);
        listTemplateSP =
customListTemplateCollection[listTemplate];
    } 

    if (listTemplateSP == null)
        // Could not found
        throw new Exception("AddList: Could not found
list template"); 

    // Ok. Add list
    Guid newListGuid = parentWeb.Lists.Add(title, description,
listTemplateSP); 

    // Get new list
    SPList newList = parentWeb.Lists[newListGuid];
    newList.OnQuickLaunch = onQuickLaunch; 

    // Return
    return newList;

}

SharePoint 2007 basics – Add a Web

For my first SharePoint post I wanted to start by
some of the basics related to working with the SharePoint Object Model. For
sure there are other posts about this on the net, but I think that my blog
should also reflect my SharePoint learning experience, and maybe by doing this
I can show different ways accomplish similar things.

So let’s begin. How do you programmatically add Web’s,
List’s and Folder’s to SharePoint?

Add a
Web

To add a web I used the SPWebs.Webs
property that returns a
SPWebCollection where
you can
Add new
Web’s. Of course that this means that you should add a web under another web
(the parent web).

So to add a web you have to give parameters like
the
title, description, relative url name, locale id, template to be
used, etc. See http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.spwebcollection.add.aspx
.

With this other things that you have to think about
are related with the
web permissions and navigation
nodes

(Quick Launch and Top Link Bar’s).

I finish with a sample function that can be used as
a starting point
.

public SPWeb AddWeb(SPWeb parentWeb, String title,
String description, String relativeUrlName, UInt32 localeId, String template,
Boolean useUniquePermissions, Boolean addToTopNavigationBar, Boolean
addToSitesQuickLaunch)
{
    // Create
    SPWeb newWeb =
parentWeb.Webs.Add(relativeUrlName, title, description, localeId, template,
useUniquePermissions, false); 

    // Default uses parent navigation
    newWeb.Navigation.UseShared = true; 

    // Test links to add
    SPNavigationNode navigationNodeToAdd
= new SPNavigationNode(title, relativeUrlName, false);
    if (addToTopNavigationBar == true)
    { // Add
        parentWeb.Navigation.TopNavigationBar.AddAsLast(navigationNodeToAdd);
    }
    if (addToSitesQuickLaunch == true)
    { // Add to Quick launch sites
section
        foreach (SPNavigationNode
navigationNode in parentWeb.Navigation.QuickLaunch)
        { // Search sites
            if (navigationNode.Title ==
"Sites")
            { // Add here
                navigationNode.Children.AddAsLast(navigationNodeToAdd);
                // Stop
searching
                break;
            }
        }
    }
    return newWeb;
}

By the way, the last part to add the navigation
node to the Quick Launch Sites section is just an example that may not work if
you are using sites in languages other than English
.