RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Wrangling SharePoint Workflows with Visual Studio : Page 2

SharePoint and Workflow may be the most powerful combination since chocolate and peanut butter, but the trick is harnessing their combined power. That isn't as easy as it first seems, but in this article you'll learn how create a SharePoint workflow in Visual Studio from start to finish.


Creating a Workflow
Enough of the theory and background, it's time to start developing a workflow.

In this example you're going to build a workflow that tracks the grading of homework assignments. The grading workflow is designed to activate whenever a document is uploaded to a specific document library. There is also a task list that informs the workflow when it has new work to do. The workflow can add to this list because it runs as a special system account. Instructors and assistants subscribe to alerts on the task list and are thus informed that a new assignment is ready to be graded.

When the instructor or assistant has reviewed the assignment they enter a numeric score as well as notes on the score into the task. This is copied back into the document in a set of fields that cannot be modified. (In a real life situation you might also integrate the workflow with a grade book program to add the grades automatically.) The grading example demonstrates a number of core workflow concepts:

  • Content Types—You'll use content types to create a custom task type as well as to create fields that cannot be edited.
  • Task Creation—Creating a task in a SharePoint workflow isn't as easy as dropping an activity on the design surface. Because this workflow relies upon tasks to take instructor input, you'll walk step-by-step through the creation of tasks.
  • Property Modification—You'll see how to make changes to the workflow item while the workflow is running.

Content Types
Every piece of information in SharePoint has a content type. The content type defines the fields that are associated with the content. It is possible, as is the case in lists, to add additional fields beyond the base content type, however, the best way to ensure that a field is present is to define a new content type.

Content types can also inherit from other content types. For instance, the default workflow task, which is used to create tasks from a workflow, derives from the standard task content type. In this example, you're going to create content types derived from the workflow content type.

Content types comprise three basic components: field definitions, field references, and the feature that you deploy them in. Let's start by defining two fields in XML (you'll use these later in this article):

<Field ID="{0116A5FF-6FB7-43e1-B3E3-30A58B40349C}"
     Name="GradingScore" Group="Grading" DisplayName="Score"
     Type="Number" Sealed="FALSE" ReadOnly="FALSE" Hidden="FALSE"
<Field ID="{81792580-6F97-4960-84C2-7A8A926D1DCE}"
     Name="GradingNotes" Group="Grading" DisplayName="Notes"
     Type="Text" Sealed="FALSE" ReadOnly="FALSE" Hidden="FALSE"

Let's walk through each of the attributes from the field definitions above:

  • ID—A unique GUID for the field. You can generate a GUID from Visual Studio by selecting Tools->Create GUID. The Create GUID application will launch. From there you can click the Copy button to copy the GUID. The GUIDs above were created in precisely this way.
  • Name—This is the internal name of the field in SharePoint. Care must be taken when naming fields so as not to collide with an internal name already used by SharePoint or with the names of other fields on the system. Note that the fields above were prefixed with Grading for this reason. These names should not contain spaces or special punctuation.
  • Group—This is the grouping that will be used to organize fields in the user interface. This name can be anything that makes sense for the application.
  • DisplayName—This is the name that will be displayed to the user when they see the field. This field may contain spaces and the special punctuation to make the field easy for the user to understand.
  • Type—This is the type of the field to be created. Here we're using the Number and Text values but Boolean, Choice, Computer, Currency, DateTime, URL, and other field types can be used as described at http://msdn2.microsoft.com/en-us/library/ms437580.aspx.
  • Sealed—If True then no one will be able to change the field in list settings. By setting them to False, the fields are modifiable.
  • ReadOnly—The field itself can be written to. If you don't set this to False (or omit it to accept the default) the field won't show up in the user interface.
  • Hidden—You might hide a field if you want to use it internally but you don't want users to be able to see it.
  • DisplaceOnUpgrade—This setting indicates that if the field definition already exists we want to overwrite it with the values in this XML fragment.

With the fields created, the next step is to create your content type and add references to the fields. In order to add the content types, you need to know how to derive from an existing content type. There's a base content type hierarchy in MSDN at http://msdn2.microsoft.com/en-us/library/ms452896.aspx. This shows the content IDs for existing types. Unlike other IDs in SharePoint, which are either an integer or a GUID, the content type Id is a special hexadecimal string that represents not only the content type itself but also its parent—sort of like a human's surname except in more detail.

There are two mechanisms for creating your content type. The first mechanism is appending a two-digit ID after the existing content type. The two-digit ID can be anything except 00. This is generally reserved for content types derived from your own content types because the potential for collision is so high (1 in 256 odds).

The other mechanism, which is recommended, is 00 followed by a GUID that has had all of its punctuation removed. This creates a longer content type ID so it's recommended only for the first level that you derive from a system type. Thereafter you should use the two-digit mechanism in order to minimize the overall length of the content type, which is capped at 512 bytes—in other words 1,024 hexadecimal characters. (You can learn more about content type IDs in the Content Type IDs entry in MSDN available at http://msdn2.microsoft.com/en-us/library/aa543822.aspx.)

The content type for the grades workflow task looks like this:

<ContentType ID="0x01080100B7336179CFFE43e59B86E241C767010E"
     Name="GradingTask" Group="Grading" Description="Grading Task"
     Version="0" Hidden="FALSE" >
     <FieldRef ID="{0116A5FF-6FB7-43e1-B3E3-30A58B40349C}"
          Name="GradingScore" DisplayName="Score" />
     <FieldRef ID="{81792580-6F97-4960-84C2-7A8A926D1DCE}"
          Name="GradingNotes" DisplayName="Notes"/>

Here the "00+Guid" method of creating the content type was used because it's the first level from a system content type. The workflow task content type is 0x010801 thus that is how this content type begins. The XML fragment also contains <FieldRef> nodes in that correspond to the fields defined above—both the ID and the Name fields match exactly.

The next content type is the content type for the document which will have the same score and notes fields but this time they won't be editable. The document content type as shown below:

<ContentType ID="0x010100ADEC125AC3C74c1bA7E3A50731525809"
     Name="GradingDocument" Group="Grading" Description="Grading Document"
     Version="0" Hidden="FALSE" >
     <FieldRef ID="{0116A5FF-6FB7-43e1-B3E3-30A58B40349C}"
          Name="GradingScore" DisplayName="Score" ShowInDisplayForm="TRUE"
          ShowInFileDlg="FALSE" ShowInListSettings="TRUE" ShowInEditForm="FALSE"
          ShowInNewForm="FALSE" ReadOnlyClient="TRUE" />
     <FieldRef ID="{81792580-6F97-4960-84C2-7A8A926D1DCE}"
          Name="GradingNotes" DisplayName="Notes" ShowInDisplayForm="TRUE"
          ShowInFileDlg="FALSE" ShowInListSettings="TRUE" ShowInEditForm="FALSE"
          ShowInNewForm="FALSE" ReadOnlyClient="TRUE" />

This document type is derived from a document (0x0101) with the same GUID method used above—but not the same GUID. The content type also includes the same fields as the task by creating <FieldRef> nodes, which match ID and Name attributes to the <Field> nodes created above. In this case, however, the fields should not be able to be written to. There is a ReadOnly attribute for the <FieldRef> but it causes the field to become hidden as well, so you can't use it. Instead, the attributes used here prevent the field from displaying on the new and edit forms. The new attributes are described below:

  • ShowInDisplayForm—The display form is the form that is displayed when the user elects to view the item or view properties of a document. This value is set to True so that the field will be displayed.
  • ShowInFileDlg—When an Office application saves the document does the field show? This is set to False since the user isn't supposed to manipulate the value directly.
  • ShowInListSettings—This shows the field in the list settings. If False the field will not be visible when changing the list. This value is True so that the field will be displayed.
  • ShowInEditForm—The edit form is the one that users get when they edit an item or edit properties on a document. Since the user shouldn't change the value the attribute is False.
  • ShowInNewForm—The new form is the one that users get when they try to create a new item. Since the user shouldn't ever set this value the attribute is False.
  • ReadOnlyClient—This attribute indicates that the client shouldn't be able to set the value of the field. This is True to prevent client side changes.

The content types are done. In order to deploy them a SharePoint feature is needed. Because the workflow will automatically create a feature, you'll use the workflow feature to deploy your content types at the same time.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date