Second whitepaper

Posted by Dave on Jun 18th, 2008
2008
Jun 18

My second whitepaper was published to MSDN: Building and Distributing Workflows in SharePoint Products and Technologies for Use in Customer and Partner Environments.

Here is the Table of Contents:

Contents

  • Overview of Workflows in Customer and Partner Environments
  • Planning and Designing for Multi-Environment Deployment
  • Defensive Coding
  • Supporting Customizations
  • When Things Go Wrong
  • Logging
  • Deployment
  • Documenting Your Workflow
  • Summary
  • Additional Resources

Enjoy!

 

Dave

Workflow Whitepaper on MSDN

Posted by Dave on Jun 11th, 2008
2008
Jun 11

I just received notice that the first of my whitepapers has been published on MSDN: Delivering Modular SharePoint Workflow Functionality. It covers the reasons and process for creating custom Activities, Actions and Conditions for SharePoint workflows. While it is ostensibly written for ISVs considering adding support for SharePoint workflows to their applications, the process and code is applicable to anyone adding custom Activities.

There is another one coming soon on how to build bullet-proof workflows that run in environments over which you do not have direct control. I’ll post when that one hits MSDN as well.

 

Questions, comments, complaints welcome…

 

Dave

SPWebConfigModification

Posted by Dave on Jun 5th, 2008
2008
Jun 5

Just a quick note here.

When you are adding a web.config entry via the SPWebConfigModification class, you need to specify a Name for the modification. Typically, it will look something like this: add[@name=\”CustomSiteMapProvider\”] . It is an XPath expression to uniquely identify the modification. The tricky part is that this name must match the name= parameter in the string added to the web.config (assuming you have one).

In other words, this is OK:

Name= add[@name=\”CustomSiteMapProvider\”]

Value= <add name=’CustomSiteMapProvider’ type=’MyNS.MyClass, MyDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxx’ description=’Custom site map provider’ NavigationType=’Global’ />

 

 

Whereas this is NOT OK:

Name= add[@name=\”CustomSiteMapProvider\”]

Value= <add name=’MyNewSiteMapProvider’ type=’MyNS.MyClass, MyDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxx’ description=’Custom site map provider’ NavigationType=’Global’ />

Note the difference in the name attribute in the Value and the Name of the modification.

This will become a problem when you attempt to REMOVE the entry. You will not be able to.

 

-Dave

2008
May 17

Thanks to everyone who attended my Code Camp session this morning, and for putting up with my “machine issues”.

As promised, here are the tools that I demonstrated:

STSDev - www.codeplex.com/stsdev

SharePoint Inspector: http://www.codeplex.com/spi

U2U CAML Builder: http://www.u2u.info/SharePoint/U2U%20Community%20Tools/U2U%20Caml%20Query%20Builder%202007%20v3.0.2.0.zip

 

SharePoint Tips Utility Pack: http://www.codeplex.com/spstipsUtilityPack

App Pool Manager: http://www.harbar.net/articles/APM.aspx

 

Reflector: http://www.aisto.com/roeder/dotnet/

“Attach to Process” script: http://www.andrewconnell.com/blog/archive/2006/05/10/3110.aspx [Note: You’ll need to change the process name in the script from “aspnet_wp.exe” to “w3wp.exe”]

 

One other thing I forgot to mention in all of the projector-problem mayhem: if you are interested in learning more about SharePoint and Office development, including FREE SharePoint developer training, please consider joining the Office Geeks User Group. We meet monthly at the Microsoft Office in Malvern. More information is available here: http://www.officegeeks.org/philly or by email: geeks_at_kcdholdings-dot-com.

Thanks again for attending this morning,

Dave

Free SharePoint Developer Training

Posted by Dave on Apr 8th, 2008
2008
Apr 8

Now that I’ve got your attention…the bad news. You need to be in the Philly area and able to come to our Philly Office Geeks meetings. Also, this is really a self-teaching opportunity. We’re going to provide the direction, information, resources and some support, but this is an opportunity for you to learn at your own pace and take things as far as you want to take them. We only meet once/month so we won’t be winning any speed-training awards. If you are interested in professional SharePoint training that gets you from 0 to 100 in 4 action-packed days, I recommend the Ted Pattison Group, specifically, the course I’m teaching in Philly in May. You can read more about it here: http://www.mannsoftware.com/Blog/?p=118

We’re kicking off the sessions at our April meeting (tonight, sorry for the short notice) by providing information on pre-reqs and information to get people started. The first actual “training” will happen at our May meeting.

With that said, here’s what you need to get started:

  1. A machine (physical or virtual) running Windows Server 2003 or 2008, all patched and updated
  2. WSS or MOSS, SP1 – trial version acceptable
  3. Visual Studio 2008. You can get by with 2005, but I’ll be demoing with 2008
  4. Lutz Roeder’s Reflector (http://www.aisto.com/roeder/dotnet/)
  5. SharePoint Designer 2007
  6. MOSS SDK: http://www.microsoft.com/downloads/details.aspx?FamilyId=6D94E307-67D9-41AC-B2D6-0074D6286FA9&displaylang=en
  7. WSS 3 SDK: http://www.microsoft.com/downloads/details.aspx?familyid=05E0DD12-8394-402B-8936-A07FE8AFAFFD&displaylang=en
  8. SQL – you can use the Express version that SharePoint installs – don’t let the VS install overwrite it
  9.  

Here are a couple of articles on setting up an environment:

However you get there, the end result needs to be a standalone SharePoint virtual environment with either MOSS or WSS, VS 2008, SharePoint Designer and the couple of tools mentioned above. We’ll be adding more tools as we go along.

Trial versions of all software is acceptable.  Also, I believe the 2 write ups above each mention installing VSTO.  We won’t need that so you can skip it.

Questions and support are being provided via our Yahoo Group: http://tech.groups.yahoo.com/group/PhillyOfficeGeeks

 

Dave

Workflow Cancellation Handlers

Posted by Dave on Mar 30th, 2008
2008
Mar 30

Another excerpt from the book:

 

Cancelling Workflows is similar in many ways to Fault Handling in our Workflows. If Fault Handlers are the catch block, then cancellation Handlers are the finally block. Workflows can be cancelled in a few ways and for any number of reasons:

    *    By unhandled exceptions

    *    By an administrator in the UI

    *    Explicitly based on a condition within the Workflow through the use of a Terminate activity

The Cancellation Handler allows us to perform any processing that needs to occur before the Workflow actually shuts down. One thing that is important to note is that there is no way to stop the cancellation of a Workflow once it has been initiated by any means.

So, if we can’t stop the cancellation of a Workflow, what can we do? The answer is really just about anything else. Off the top of my head, the following comes to mind:

    *    Notify a document owner that the Workflow has been cancelled

    *    Notify participants that the Workflow has been cancelled

    *    Just like with Fault Handling, if Tasks were already assigned, you should go back and either delete them or flag them as inactive.

    *    Again just like Fault Handlers, log the cancellation

 

So, with all of that out of the way, how do we actually catch a Workflow Cancellation event and respond to it? As I said when I started out this section, it is similar to Fault Handling. To work with the Cancellation Handler for the whole Workflow, click on the middle tab at the bottom of the designer palette (and shown above in Figure 9-4). This will reveal another palette used specifically for handling Workflow cancellations.

 

Also, composite activities can also contain specific, local Cancellation Handlers. This local Cancellation handler will be called if one of their child activities is cancelled, or executing when the Workflow is cancelled. Access this via a similar mechanism to the Fault Handler – right click on the activity and select View Cancel Handler.

 

One thing to note about Cancellation Handlers is that they may not exactly execute as you would expect. If you place a Cancel Handler globally on the entire Workflow, it would be logical to assume that it would fire any time the Workflow is cancelled – for any reason. Unfortunately, this is not the case. Because Cancellation can be handled locally, only the composite activities that have children executing at the time the error is thrown or the Workflow otherwise cancelled will have their Cancellation Handlers triggered. So, in the case of the global Cancellation Handler, this will only be triggered if the whole Workflow is cancelled – typically by an Administrator via the user interface.

 

In other cases, in order to get multiple activities executing simultaneously, you really need to be using the Parallel activity. If one branch of the Parallel activity causes the Workflow to be cancelled – for example by throwing an unhandled error, the other branch(es) of the Parallel activity will be notified that the Workflow is being cancelled. Individual composite activities within those other branches will also have their Cancellation Handlers triggered. However, the Parallel activity itself and the Workflow as a whole will not have their Cancellation Handlers triggered.

 

It’s all a little bit happenstance and highly dependent upon execution order, timing and which activities are executing at the time the cancellation is triggered. While you can generally plan out your Cancellation Handlers pretty well, there will be an experimentation aspect to it to see how things execute in your environment.

NOTE    For an example of the variable nature of Cancellation Handlers, in a nod to Mr. Heisenberg, I could consistently produce different results just by alternating between running my test Workflow in the debugger or outside the debugger. As I said, this all highly dependent upon exactly what is happening at the moment the cancellation is triggered. Your mileage may vary.

 

Workflow Rules Engine

Posted by Dave on Mar 30th, 2008
2008
Mar 30

One of the least used and perhaps least understood aspects of Windows Workflow Foundation (and therefore SharePoint Workflow) is the Rules Engine; which is a shame because it is an extremely powerful tool. To help remedy this, I present the following excerpt from the book: Workflow Rules. Also available is the source code for the solution covered in the PDF: Chapter8_Source.rar.

The PDF covers the Rules Engine in nitty gritty detail - everything you ever wanted to know and then some.

The solution covers a rudimentary sample application that allows non-technical business users to modify the rules that control how a workflow processes. It has its shortcomings, not the least of which is that as it currently stands it is a Windows app that must be run on the SharePoint server, but it is a decent sample of what is possible.

I hope this will help you understand this tool and how it can help you build powerful, flexible SharePoint workflows.

Enjoy!

Dave

SharePoint Workflow: Fault Handling

Posted by Dave on Mar 30th, 2008
2008
Mar 30

We’ll handle this one with an excerpt from the book

The functionality provided by fault handling in our workflows is no different from what you expect in typical .NET applications: you try something and then catch any errors and handle them. The implementation, however, is turned 90 degrees from what you would expect. Starting from the top, fault, or error, handling in our workflows is going to have the same capabilities as any other .NET application:

  • Faults can be caught within a local scope, or globally for the entire workflow.

  • Unhandled exceptions will cause the workflow to immediately halt execution and shut down.

  • Handled exceptions can be processed and allow your workflow to either continue processing or shut down gracefully, with as much logging or notifications as you need.

We’ll cover the details on these as we go through the rest of this section. First, let’s review some of the mechanics of how you configure fault handling in workflows. The primary construct for handling errors is the FaultHandler activity. We’ll walk through using this activity in just a bit, but at a high level, each FaultHandler activity is associated with one particular type of exception and contains other activities that dictate how the particular error is handled.Like any other error handling, the goal of fault handling in WF is to trap errors as they occur, respond according to our business rules, and ideally allow the workflow to continue processing. If continuation is not possible, we need to clean things up and return our documents or other content to a stable, manageable state.At a global level, exception handling can be applied to the entire workflow. To do this you are going to make use of the three little tabs (shown in Figure 9-4) at the bottom of the Workflow Designer pane in Visual Studio that we haven’t paid much attention to as yet. Specifically, we’re going to focus on the rightmost tab.


Figure 9-4. The tabs at the bottom of the Workflow Designer in Visual Studio provide access to the fault handling functionality.

Clicking on that tab will reveal the Workflow Exceptions design canvas, shown in Figure 9-5. Even the most cursory glance will reveal that the Exceptions design canvas looks nearly identical to the Workflow Designer we’ve worked with so far. That is not an accident. Configuring our exception handling is just configuring another part of the workflow. Looking at Figure 9-5 a little more closely, you’ll see it consists of a single composite activity of type faultHandlersActivity. This composite, like all of the others we’ve seen so far (Sequence, Parallel, While, IfElse, etc.) is made to serve as a container for other activities. This one is a little special, though, because it is made to store only one type of activity: the FaultHandler activity mentioned earlier.  If you try to add any other type of activity to it, the Designer will not let you.   If you try to add any other type of activity to it, the Designer will not let you.


Figure 9-5. The Workflow Exceptions design canvas looks remarkably like the regular Workflow Designer canvas we’ve already worked with.

One other thing that is different about this composite activity is the manner in which it displays its children. Because each of the children is another composite activity, the tree display could get very ugly, very fast. To help alleviate this, Microsoft has coded the faultHandlersActivity to display its children in a unique way - essentially each FaultHandler gets its own design canvas. Each FaultHandler child dropped onto the faultHandlersActivity parent will be displayed in the small ribbon-like construct at the top of the activity. The two blue arrow icons allow you to scroll back and forth between the FaultHandler activities that have been added. The main body of the activity below this will display the child activities from the currently selected FaultHandler.That’s a little confusing. Let’s walk through an example to help clarify things:

  1. Open or create any workflow.

  2. From the designer canvas, click the right-hand tab located at the bottom of the screen. This will open the Workflow Exceptions design canvas.

  3. From the Toolbox, drag two FaultHandler activities and drop them onto the faultHandlersActivity on the canvas

  4. Click on the first FaultHandler activity—indicated by this icon on the left side: 

  5. Drag a Code activity and drop it into the body of the faultHandlerActivity1 activity - where the small green plus sign has appeared.

  6. Click on the second FaultHandler activity - indicated by same icon shown in step 4, this time on the right side. Notice that the Code activity has disappeared. This is because we are now working with a different FaultHandler activity.

  7. Drag an IfElse activity from the ToolBox and drop it into the body of the faultHandlerActivity2 - again where the small green plus sign has appeared. Add another Code activity to the left-hand branch.

  8. Click back on the first FaultHandler - you’ll see that the Code activity is still in place.

If you click back and forth between the two FaultHandler activities, you’ll see that everything is still intact - you just have two totally distinct environments in which to handle errors. This, of course, begs the question of why you need separate environments. The answer is that you need multiple environments in order to explicitly handle different types of errors. It is the equivalent of the code shown in Listing 9-1.

Listing 9-1. The Code Equivalent for Our Workflow Fault Handling Constructs

try

{

//do something

}

catch (System.NullReferenceException exNull)

{

//handle a null reference exception

}

catch (System.ArithmeticException exArith)

{

//handle an arithmetic exception

}

catch (System.Exception ex)

{

//catch-all to handle any other error

}

 Each FaultHandler activity represents one of the catch blocks in Listing 9-1.

Configuring Fault Handlers

There are two ways to configure fault handling for our workflows - declarative or imperative. The imperative type of fault handling requires setting one set of properties, creating variables, and writing some code to handle the error however we need to. We’ll show this option in a minute. Declarative handling is slightly different. When we handle our workflows declaratively, we work exclusively in the Designer - adding activities to the canvas and setting properties to handle our exception. We don’t write any code. We’ll cover this next.

Declarative Fault Handling

Declarative fault handling is all about adding activities to the canvas and configuring them to handle the exception according to your business rules. One of the primary distinctions of this approach is that it is somewhat generic in nature; the only real information you know about the fault is its type—and that only because, as we saw earlier, each FaultHandler is configured to handle a particular type of error.So, how do we work with this style of fault handling? As you would expect, it’s really pretty straightforward if you’re comfortable with the Workflow Designer.

  1. From the Exceptions tab in the Workflow Designer, drag a FaultHandler activity out onto the canvas.

  2. Make sure that the FaultHandler activity is selected and open the Properties window.

  3. Inside the Properties window click on the ellipsis for the Fault Type property. This will bring up a dialog box, shown in Figure 9-6. This dialog box allows you to specify which type of error this particular FaultHandler activity will take care of.

  4. Once you’ve specified the type of error to be handled by this FaultHandler activity, you can add whatever activities you need to in order to handle the error.

  5. If you need to handle more than one exception type, drag another FaultHandler activity out and configure it in the same way.

OK, I have to jump in here and editorialize a bit. I don’t understand the usefulness of declarative fault handling (except for one circumstance, which I’ll get to in just a minute). Here’s the problem I see - if I’m catching and handling an error, I want to be pretty specific about the way I handle it. Also, in most cases, the error being thrown is likely unique to the workflow that is running. Because of these two points, I need my handler to be specific, which means that I’m likely adding a Code activity and writing some code. Once I’ve crossed that line, I’m into the realm of imperative fault handling. The only exception I see to this is if all you are doing is simple logging. In that case, write a custom, generic logging activity that will write the information to whatever logging medium you require, add it to the Designer for your fault handler, and you’re good to go. No coding required, but you still get some useful information and didn’t have to write any code specific to this handler.  Other than this one case, I recommend that you read on and understand the benefits of imperative fault handling—it’s a little more work but well worth it for the extra value, as you’ll see.


Figure 9-6. This dialog box indicates which type of exception is handled by our FaultHandler activity.

Imperative Fault Handling

Imperative fault handling, as I alluded to earlier, is a little more involved than simple declarative handling. However, it gives us a lot more control and a lot more capability to manipulate our handler process and to be specific with how we process our faults. Imperative fault handling makes use of one new property of the FaultHandler activity: the Fault property. The Fault property allows us to create a property that will be used to store the object representing the exception that was thrown by our workflow. With that, we can then handle our exception however we need to, typically within a Code activity. When the exception is thrown, we will have access to the entire Exception object through the variable referenced in the Fault property.To make this work, follow these steps:

  1. Repeat steps 1 - 3 from the previous section.

  2. Right-click on the FaultHandler activity and select Promote Bindable Properties from the context menu.

  3. Take a look in your code-behind file and you’ll see that a new dependency property, named <Fault_Handler_Activity_Name>_Fault1, has been created for you. For example, if your fault handler is named faultArgExcep, then the dependency property will be called faultArgExcep_Fault1. The new property will have a type of System.Exception. If you choose to, you could make the type for this variable more specific.

  4. You’ll still need to fill in the FaultType property to tell the workflow runtime which type of error this particular handler is taking care of. For this example, you can type in System.Exception.

That’s it. If your workflow ever triggers this handler, your dependency property will store reference to the exception that was thrown. You can drop a Code activity onto the canvas, reference the dependency property, and do with it whatever you need to do in order to handle his error. The main benefit is that you have a lot more information about the error available to you. To harp on logging again—placing some of this information (stack trace, source, etc.) into our logging is going to make errors much easier to troubleshoot.

Local Scope

So far, we’ve looked at fault handling at what is essentially the global level. We’ve created handlers for faults that bubble up, unhandled, to the top of the chain - the workflow itself. One definite problem with this is that when you are capturing errors at the workflow level, there is no way to continue the workflow after the error has been handled. Faults caught at the workflow level always immediately precede the termination of the workflow. This is obviously less than desirable. So, what can we do about it? Fortunately, there is an option. Faults can also be handled at the level of any composite activity, so the Parallel, Repeater, Sequence, and While activities (just to name a few) can all handle faults at a more granular level.Handling the errors at the level of a composite activity is exactly the same experience as we saw at the global level. The only thing that is different is how you access the fault handler design canvas for a specific composite activity—simply right-click on the activity itself and select View Fault Handlers from the context menu. That’s it. The rest is identical to what I described earlier.

TipWith the scope issues discussed in this section in mind, I recommend that you make judicious use of some of the composite activities that ship with WF. Certainly the Parallel, IfElse, and While activities have their place by performing a specific function in addition to being composite activities. There is, however, the Sequence activity, which can be used when you are executing activities serially but still need to be able to handle faults locally.

If an error is not explicitly handled at a local scope, it will bubble up to the global handler to attempt to be handled there. If the global handler does not take care of the error, the workflow will error out with unpredictable results - including potentially leaving your documents or tasks in unknown states.

Fault Handling Summary

So now we have a pretty good idea of how we go about handling faults in our workflows. The only thing that I’d like to conclude this section with is a brief discussion of how you should handle errors in your SharePoint workflows:

  • As I alluded to previously, you should always log the error. Whether this is with code or a logging activity is entirely up to you. I’ll just leave the recommendation at this: log it somewhere.

  • Local, local, local. Whenever possible, handle your faults as locally as possible.

  • Always, always provide a catchall fault handler at the workflow level. Add a FaultHandler activity at the workflow level and configure it to catch exceptions of type System.Exception. If it does nothing else, log the error details somewhere.

  • If tasks were already assigned, you should go back and either delete them or flag them as inactive. Specific details around this would be dependent on your particular business requirements, but it wouldn’t do much good, and could potentially be very confusing, if participants had tasks assigned to them for a workflow that had errored out.

CautionIf you are going to undo changes in your workflow because of an error, you should understand how workflows process operations in batches and do some experimentation with your particular situation. Go back and read the section “Workflow Processing” earlier in this chapter before proceeding too far down this road. Specifically when your workflow will commit operations to the database is unique to every workflow. Keep this in mind as you plan your fault handling.

SharePoint Training

Posted by Dave on Mar 18th, 2008
2008
Mar 18

News Flash!!!

I’m going to start conducting SharePoint training through the Ted Pattison Group. My first course is in May and second is in June:

 

More courses will be scheduled soon to fill out the rest of the year. The training location is conveniently located in King of Prussia: http://www.mclabs.com/facilities/philadelphia.aspx

Here’s more information on the courses:

WSS401

Format:

Instructor-led Training with Hands-on Labs

Audience:

Professional .NET Developers

Length:

4 Days

Description:

This intensive 4-day course explores design and development techniques used when building business solutions with Windows SharePoint Services 3.0 (WSS). The lectures and lab exercises on the first day dive into the WSS object model, developing WSS features and creating solution packages to deploy your development efforts in a staging or production environment. The course covers advanced developer topics such as creating custom application pages, page templates, provision pages and site branding using Master Pages. You get hands-on experience writing and testing Web Parts, Content Types, event handlers, custom workflows and site definitions. Along the way, you will also learn how to write WSS event handlers that read, modify and generate Office 2007 documents using the Office Open XML File Formats as well as how to program security using the WSS object model to manage users, groups and permissions on sites, lists and document libraries.

Prerequisites:

Attendees should have professional development experience with Visual Studio 2005, the .NET framework and ASP.NET as well as familiarity with Microsoft Office products such as Word and Excel. It is also recommended (but not required) that attendees have a background with the previous version of Windows SharePoint Services V2 and have experience working directly with XML files in Visual Studio 2005.

 

 

SPW401

Format:

Instructor-led Training with Hands-on Labs

Audience:

Professional .NET Developers with WSS Fundamentals

Length:

4 Days

Description:

This intensive 4-day course explores design and development techniques to create SharePoint Workflow Templates using Visual Studio. The course quickly moves beyond fundamental programming techniques with WSS and Windows Workflow Foundation and gets into the meat of creating real-world workflow templates for SharePoint-based business solutions. You will learn how to program against the SharePoint Workflow API as well as how to integrate input forms using both .ASPX pages and InfoPath forms. The course will also discuss developing custom activities which can be integrated with SharePoint Designer 2007.

Prerequisites:

Attendees should have attended WSS401 or GSA401 or have equivalent knowledge as professional developer already comfortable with Windows SharePoint Services development. It is recommended that attendees have experience developing of the Windows Workflow Foundation platform within Visual Studio.

 

If you’re interested in learning about SharePoint development in general or workflow specifically, these are the courses you want to attend. Ted’s material is second-to-none.

Feel free to ping me if you have any questions, or visit Ted’s website: http://www.tedpattison.net for more information.

 

-Dave

 

 

STSDev Tool 1.2: Generating Workflow Activities

Posted by Dave on Mar 17th, 2008
2008
Mar 17

I finally got my act together and posted the updated version of Ted Pattison’s STSDev tool on CodePlex. This is the tool I demo’d at Office DevCon and the piece I added is the functionality to generate a functionally complete custom workflow activity plus all of the pieces to convert it to a SharePoint Designer Action/Condition. The tool is available here: http://www.codeplex.com/stsdev.

As a side note, I have a lot of ideas to enhance this tool because I really think it holds a lot of potential. I’m going to step away for a little bit and work on the Workflow Monitor application I showed at the SharePoint Conference, but then plan on getting back to this tool and adding some more “stuff”

-Dave

Next »