SharePoint Designer Workflow in a Nutshell

Microsoft released SharePoint Designer as a free download on April 2, 2009. One of the most powerful features of SharePoint Designer is the ability for non-programmers to easily create business tailored workflows to improve their business process management.

So, What Is a Workflow Anyway?

Workflows are just what their name implies, flows of work. Think of any process where some set of actions are performed, such as buying an item in a store, taking a shower, filing a letter, or even dating someone special. All of these tasks are composed of tasks or states where some action or event is expected.

Let’s take a look at one of them, buying an item in a store.

When you buy an item, you need to do the following:

1. Find the correct item.
2. Take the item to the counter.
3. Receive the price from the attendant.
4. Decide between using cash or using a credit card.

If using cash:
5a.1 Give appropriate amount to the attendant.
5a.2 Receive any change.
5a.3 Verify change.
5a.4 Pocket change.

If using a credit card:
5b.1 Give credit card to the attendant.
5b.2 Receive receipt for signature.
5b.3 Verify amount.
5b.4 Sign receipt.
5b.5 Return receipt to the attendant.

6. Put pen in pocket.
7. Retrieve item, and run before the attendant notices the missing pen.

Don’t be fooled. This task may seem simple, but that’s only because we do it so often it has become routine. Several of these steps require an amount of substeps, and any failure will need to be handled according to some set of rules.

A workflow structures such processes into manageable chunks called activities. Each activity performs one or more small operations, such as verifying an amount or stealing a pen, and the workflow makes sure that everything is done in order and handles exceptions to the regular flow.

Workflows in SharePoint

SharePoint integrates tightly with Windows Workflow Foundation, or WF, and workflow is an integral part of SharePoint.

By default, the free version of SharePoint, Windows SharePoint Services, include only a single simple workflow, the Three-state workflow. The more advanced, and for-purchase version of SharePoint, Microsoft Office SharePoint Server 2007, include more workflows, such as Approval workflow, Collect Signatures workflow, and Disposition Approval workflow.

However, the true power of workflow in SharePoint comes from being able to design specific workflows that can adapt to and support an organization’s needs.

Businesses Needs Workflow

Most, if not all, businesses have business specific processes that will benefit from having at least some degree of automation. If nothing else, workflow enables organization to include auditing of business processes.

However, most businesses and organizations are also unique. Creating generic workflows that can be applied to many different organizations is difficult and not even desirable, because each organization works in different ways.

Not just that, but business processes change. Even if a business invests in custom developed workflow solutions, chances are, those solutions will require massive re-design frequently. Having a workflow solution that allows businesses to adapt their business processes as requirements change will greatly increase organization flexibility.

SharePoint Designer Workflow to the Rescue!

Perhaps the biggest advantage of developing workflows in SharePoint Designer is the ease of development. Most end users can create tailored workflows with just basic training. When business needs change, the same end users can adapt the workflows to support the changing needs.

A SharePoint Designer workflow workflow is an easy, cheap, and somewhat limited entry point to workflow development.

They’re easy, because most end users and administrators can become workflow developers without too much training.

They’re cheap, because both SPD and SharePoint are now free, and the learning curve is gentle.

They’re somewhat limited, because, despite workarounds and extensibility, SharePoint Designer workflows are designed for ease of development and lack several of the more powerful options available in other workflow design products.

Despite these limitations, however, SharePoint Designer remains a very powerful option for:

– Organizations without specialized workflow programmers

– Organizations with frequently changing needs

– Organizations with limited budgets or high return on investment requirements

Where can I Learn SharePoint Designer Workflow

If you, or your organization, want to explore the powers of SharePoint Designer workflow, you have several options.

For online training, EndUserSharePoint.com provides a free 5-part series of SharePoint Designer workflow videos. These videos will introduce you to developing SPD workflows, but also show some advanced features, such as looping and iterative SPD workflows.

Understanding SharePoint Journal also has several resources available on the newly launched website http://www.sharepointdesignerworkflow.com/, including Issue 4 of the journal, titled SharePoint Designer Workflow and volume 2, issue 2, titled SharePoint Designer 2010 Workflows.

Besides these options, Microsoft also has several videos and tutorials available at their site. Woody Windischman has also recently released a book, titled Professional Microsoft Office SharePoint Designer 2007 that includes a very good chapter on workflow as well.

.b

Found this article valuable? Want to show your appreciation? Here are some options:

a) Click on the banners anywhere on the site to visit my blog's sponsors. They are all hand-picked and are selected based on providing great products and services to the SharePoint community.

b) Donate Bitcoins! I love Bitcoins, and you can donate if you'd like by clicking the button below.

c) Spread the word! Below, you should find links to sharing this article on your favorite social media sites. I'm an attention junkie, so sharing is caring in my book!

Pin It

User Experience Week on SharePoint Magazine – One week of SP User Experience articles

Some of you may have wondered what happened to the Customizing the SharePoint User Experience series that started last fall. The first two articles looked at sites architecture and modifying the default user experience, but then there were no more articles.

That is all about to change, however. Starting on Monday, SharePoint Magazine will hold a User Experience week, each day publishing a new article from the series.

The Customizing the User Experience of SharePoint series aims to explain how the user experience works, from how the interface is built down to details on how columns of lists get created.

Here is an article outline for the six parts:

Part 1: Overview of the default SharePoint interface from a technical point of view

In the first article we will look at how the default SharePoint interface is built. We will look at a site, going from top-down, explore some of the the default lists, the fields used to create the basic field types, which content types are available, and how list forms are rendered.

Part 2: Modifying the default experience

This article will show you which options are available for you to modify and improve the default setup. Learn how to override the default rendering of fields or forms without voiding your supported state.

Part 3: Lists and custom list forms

The third article will cover the basics of customizing lists using different views, custom list forms, and fields.

Part 4: Content types user interface

The next article will explore how you can utilize content types to display different input forms and display forms.

Part 5: Custom fields deep dive

Ever wanted to create a new field type? SharePoint enables you to do this and it is a very powerful tool for customizing the user experience.

Part 6: Fast track to feature generation

Writing custom lists with content types by hand can take a massive amount of time. In the final installment I will share with you some tools and techniques that makes list, field, and content type generation very fast.

The first two parts are already out, and if I remember I will update the links as the articles are released.

Oh yeah, to the math geniuses among you: I know there are only four articles left and there are five work days next week. You’ll just have to hang around to see how that’s going to be solved.

.b

Pin It

Consuming RSS or Atom feed in SharePoint using custom list, SPFolder, CustomAction, and NewPage

This article will demonstrate several techniques:

- Creating a list from a custom NewPage page

- Consuming an RSS feed into a SharePoint list

- Using a CustomAction with a code-behind assembly to update the feed

- Storing and retrieving custom list data in the SPFolder of the list

Yeah, I have missed writing online. And I have a ton of new ideas for articles for the next months. Make sure you follow the feed to keep up.

What you will need:

- SharePoint

- Visual Studio

- WSPBuilder

- Argotic Syndication Framework

The Argotic Syndication Framework is a free framework that has some really nice syndication features. Before you continue you should get that framework and install it.

The outline of the project we will create is as follows:

We will create a new list template. I will base this template off the custom list template and leave list creation details for you to want to read in the best SharePoint book ever. And it saves time… Our new list template will use the NewPage attribute to customize the list creation.

In our newly created list we will store feed items, either from an RSS or an ATOM feed. To store custom data, such as the feed Url and the last updated time, we will use the property bag of the SPFolder object.

Finally we will add an update button using a CustomAction element. Clicking the button will update the feed with new items.

You can see a demo of the entire solution here:

 

…or download it for you offline amusement at Googlepages.

Ok, on to the solution.

Adding ListTemplate element

Start out with a new WSPBuilder project. Name it whatever you like, I’ve called mine AdvancedListSample.

Add references to the four Argotic Framework assemblies that were installed, probably to C:\Program Files\Argotic\Microsoft .NET 2.0.

Next, add a new Feature with Receiver WSPBuilder item. You will find this item when you add a new item to the project, it should be listed under the WSPBuilder item type. I have called this item AdvancedList in my example.

Why add a feature with a receiver? Well, if you do, WSPBuilder will save you some time by creating a signing key, signing the assembly, and giving you the strong name of the assembly, which we will need later.

WSPBuilder will now create a folder structure for you that mimics [12] and the feature folder beneath it. Inside your feature folder, create a new folder called AdvancedList as well, just because I feel particularly uncreative today. The naming of this folder is important as it will hold the schema.xml file for our custom list template. The name of the folder must match the Name attribute of the ListTemplate element.

Next, to take an extremely simple approach, go to the [12]\TEMPLATE\FEATURES\CustomList\CustList folder and copy the entire schema.xml file from that folder. Paste the complete schema.xml file into your own solution. You can accomplish this by drag-and-dropping the file from CustList to your solution.

Your feature folder in solution explorer should now look like this:

RSS_in_SharePoint01

While you are in the [12] folder, open the [12]\TEMPLATE\FEATURES\CustomList\ListTemplates\CustomList.xml file and copy the Element inside that file. Paste the Element from CustomList.xml into you own elements.xml file. Then, modify the ListTemplate element as such (changes in bold)

http://schemas.microsoft.com/sharepoint/">
        NewPage="AdvancedListCreation.aspx"
      Name="AdvancedList"
      Type="10010"
      BaseType="0"
      OnQuickLaunch="TRUE"
      SecurityBits="11"
      Sequence="410"
      DisplayName="Advanced list"
      Description="$Resources:core,custList_Desc;"
      Image="/_layouts/images/itgen.gif"/>

If you feel like it, modify other attributes as well, but it is not necessary for our solution.

The NewPage attribute refers to a url in the Layouts folder. If you specify this attribute SharePoint will link to your custom page rather than the default Create List page. In our case, since we want the user to input additional data, we need to customize that page. More on that in a moment.

Great, ListTemplate code complete. On to the custom NewPage.

Custom list creation page

Next we want to add the page we will use to create our new list. Note that when you use a custom create page you will be responsible for actually creating the page. however, doing so is rather trivial in our case.

First, add a new folder to Solution Explorer, under the Template folder. Name the new folder Layouts. WSPBuilder will make sure that any file we put inside this folder will get provisione
d to the LAYOUTS folder and be available to our site.

In the new Layouts folder, add a new text file and name it AdvancedListCreation.aspx or the same name you used in the NewPage attribute. By adding a text file but naming it .aspx Visual Studio will recognize our file as an ASP.net page even if we are not developing a web solution.

Before we add any content to our new page, however, we want to set up the code-behind file. WSPBuilder has already created a FeatureCode folder for us containing an AdvancedList.cs file. You can use that file, or create a new one, but modify the content as such:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
using Argotic.Syndication;

namespace AdvancedListSample
{
    public class AdvancedList : LayoutsPageBase
    {
    }
}

This is all we need for now, we will add plenty of logic to this file later.

Note that we are inheriting from the LayoutsPageBase. This class will give us some free stuff with regards to security for pages stored in the Layouts folder.

Back to the AdvancedListCreation.aspx page we now need to reference our new page code behind class. To do so, add the following code to the top of the page:

<%@ Assembly Name="" %>
<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" Inherits="AdvancedListSample.AdvancedList" %>

Note that Visual Studio will complain about not finding the master file:

Error    1    File ‘~/_layouts/application.master’ was not found.   

It will also complain about the PlaceHolderMain later. You can safely ignore these errors.

The Name attribute of the Assembly tag must be set to the strong name of your assembly. However, since we used a feature with receiver earlier, WSPBuilder has both signed and written the strong name for us. It is stored in the Feature.xml file:

RSS_in_SharePoint02

Just copy the string from the ReceiverAssembly attribute and paste it into the Name attribute of your Assembly tag.

Cool trick, eh? No more using reflector or crafting the strong name from the GAC.

Oh, and important: Delete the ReceiverAssembly and ReceiverClass attributes from the Feature element now, we won’t use them and they will cause our feature activation to crash since we have changed the class.

Adding content and code-behind to the custom page

Next it is time to add some content to our page. For your own scenarios you will of course add different fields, but stick with this example for the moment and get adventurous later, will you?

Add the following code to the AdvancedListCreation.aspx:


   

       
           

           

       

       

           

           

       

       

           

           

       

       

           

           

       

   

                               
                                /Lists/
                               
                           

Yeah, I’m using tables for layout. So sue me, I’m lazy.

In the demo video I also had an updatefrequency field, but I removed it here since I’m not using it.

Switch back to the AdvancedList.cs file, the code behind file for our page, and add the following code to the class. I’ve added inline comments where appropriate:

public class AdvancedList : LayoutsPageBase
{
    protected TextBox tbListName;
    protected TextBox tbListUrl;
    protected TextBox tbFeedUrl;
    protected Button buSubmit;

    protected override void OnInit(EventArgs e)
    {
        EnsureChildControls();
        buSubmit.Click += new EventHandler(buSubmit_Click);
    }

    void buSubmit_Click(object sender, EventArgs e)
    {
        // Get reference to current website
        SPWeb web = SPContext.Current.Web;

        // Create new list and get reference to list and SPFolder
        Guid listId = web.Lists.Add(tbListName.Text.ToString(), "", "Lists/" + tbListUrl.Text.ToString(), Page.Request["FeatureId"].ToString(), 10010, "100");
        SPList newList = web.Lists[listId];
        newList.OnQuickLaunch = true;
        SPFolder listFolder = newList.RootFolder;

        // Add custom data to the SPFolder
        listFolder.Properties.Add("FeedUrl", tbFeedUrl.Text.ToString());

     &#1
60;  // Get feed using Argotic Syndication Framework           
        Uri FeedUrl = new Uri(listFolder.Properties["FeedUrl"].ToString());
        GenericSyndicationFeed feed = GenericSyndicationFeed.Create(FeedUrl);

        // Iterate the feed
        foreach (GenericSyndicationItem feedItem in feed.Items)
        {
            // Create new SharePoint items for each feed item
            SPListItem listItem = newList.Items.Add();
            listItem["Title"] = feedItem.Title;
            listItem.Update();
        }
        // Update the LastUpdated time
        listFolder.Properties.Add("LastUpdate", DateTime.Now);

        // And then save the changes to the folder and the list.
        listFolder.Update();
        newList.Update();

        // Redirect user to newly created list.
        Page.Response.Redirect(newList.DefaultViewUrl, true);

    }

}

What we are doing here is just to add protected properties that match the controls we put in the ASP page. By doing this we can access the controls directly from the code behind.

Next we override the OnInit method and add an event handler to the submit button. That submit button event just creates the list for us and then uses Argotic to get the feed items.

Now, this latter part requires a bit of explanation. First of all, note that we are getting a reference to the SPList.RootFolder. The reason is that we want to store custom data in our list. However, unlike many other objects, SPLists do not have property bags to store custom data. They do have a folder object, though, and the SPFolder objects to have property bags.

So, we are retrieving the RootFolder to store the custom properties, such as feed url and the time when we last updated items from the feed.

I won’t explain the Argotic details, both because they are extremely simple and because the documentation explains everything very well.

Next, feel free to deploy your solution and activate the new feature to see what happens. You should get your list template in the Custom lists column of the Create page.

RSS_in_SharePoint03

You should also see your new custom create page when you click the link.

RSS_in_SharePoint04

You should even get the expected results, a new list containing the items from the feed you entered, when you hit Create list. Still, we want more. We want to be able to update our list on demand.

Adding CustomAction to update feed

What we are going to do now is add that fancy Update feed button to our toolbar.

RSS_in_SharePoint05

The way we are going to do this is by using a CustomAction. CustomActions are great for expanding the existing menus of SharePoint. In out example we will be adding the CustomAction using the elements.xml file and adding our logic to a code-behind file.

First, add a new empty class to your solution. I have called mine AdvancedListUpdater.cs. As always call it whatever you like in your own project.

In the new file, add the following code:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
using System.Web.UI;
using Argotic.Syndication;
using Argotic.Common;

namespace AdvancedListSample
{
    public class AdvancedListUpdater : WebControl
    {
        protected override void OnLoad(EventArgs e)
        {
            EnsureChildControls();
        }

        protected override void CreateChildControls()
        {
            LinkButton link = new LinkButton();
            link.Text = "Update feed";
            link.Click += new EventHandler(link_Click);
            this.Controls.Add(link);

            Label lastUpdated = new Label();
            lastUpdated.Text = " Last updated: " + SPContext.Current.List.RootFolder.Properties["LastUpdate"].ToString();
            this.Controls.Add(lastUpdated);
        }

        void link_Click(object sender, EventArgs e)
        {
            SPList list = SPContext.Current.List;
            SPFolder listFolder = list.RootFolder;
            Uri FeedUrl = new Uri(listFolder.Properties["FeedUrl"].ToString());
            DateTime lastUpdated = (DateTime)listFolder.Properties["LastUpdate"];
            GenericSyndicationFeed feed = GenericSyndicationFeed.Create(FeedUrl);
            foreach (GenericSyndicationItem feedItem in feed.Items)
            {
        &#16
0;       if (feedItem.PublishedOn > lastUpdated)
                {
                    SPListItem listItem = list.Items.Add();
                    listItem["Title"] = feedItem.Title;
                    listItem.Update();
                }
            }
            listFolder.Properties["LastUpdate"] = DateTime.Now;

            listFolder.Update();
            list.Update();
        }

    }
}

The CreateChildControls method adds two controls, a linkbutton and a label, and attaches an event handler to the linkbutton. The label is updated with the LastUpdate property of the root folder of the current list. This is the property we stored when we created the list and will be updating when we update the feed.

The link_Click handler gets a reference to the current list (using SPContext.Current.List) and gets the SPFolder object of that list. We then, similarly to the creation process, iterate through the items. We only update items that have been published after the last update time, however, do avoid duplicates. You might want to add better logic for this.

Yeah, and you do want to add error handling. I haven’t here. You must add error handling. For crying out loud: ADD ERROR HANDLING!

Final step is to add the actual CustomAction in the elements file. Open the elements.xml and add the following code:


  ControlAssembly=""
  ControlClass="AdvancedListSample.AdvancedListUpdater"
  RegistrationType="List"
  RegistrationId="10010"
  Location="ViewToolbar"
  Title="Update Feed"
  Sequence="400">

In the ControlAssembly, add the strong name of your assembly, the same string you added to the top of the ASPX page.

Notice that since we are using the ControlAssembly and ControlClass attributes we get code-behind logic. That is the logic we added in the AdvancedListUpdater.cs just now.

Build, deploy, and test!

If everything works as expected: Great, you’ve been good.

If you didn’t get the expected results: Retrace your steps. Or, send me feedback about what didn’t work, at furuknap<[at]>gmail.com or as a comment and I will be sure to help out if I can.

Or, you can download the entire solution from here

.b

Pin It