Posts mit dem Label Workflow werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Workflow werden angezeigt. Alle Posts anzeigen

14 Dezember 2009

Workflow Designer Tipps und Tricks

Custom Activities sind cool: Sie erlauben, komplexe Teillogik eine Workflows in eine eigene Klasse / Activity zu packen, und dann den eigentlich Workflow schön schlank zu halten. Wenn nur nicht der Standard Workflow Designer im Visual Studio dann sämtliche Activities in der Custom Activity wieder anzeigt:

image

Das NERVT gewaltig. Jedenfalls mich persönlich. Zum Glück gibt es - wie für die meisten Probleme - dafür auch eine einfache Lösung: Einen Custom Designer per Attribut auf die Custom Activity setzen. Was jetzt kompliziert tönt, ist ganz einfach, da der Custom Designer nur deklariert werden muss, und gar keinen eigentlichen Code enthält.

    [Designer(typeof(MyDesigner), typeof(IDesigner))]
public partial class HandleGroupReview : SequenceActivity
{

private class MyDesigner : ActivityDesigner { }

// … A lot of workflow code …

}



Anschliessend muss noch das Attribut “Designer” auf der Custom Activity Klasse gesetzt werden und der oben abgebildete Workflow sieht schon wieder viel aufgeräumter aus.



image

02 November 2009

How to set a Correlation Token Property on a Custom Activity


I like to break up my sharepoint workflows into several custom activities, especially when there are many repetitive tasks involved. But I've always struggeld with one thing: when I needed to send an email from such an activity, I had to pass the correlation token of the onWorkflowActivated activity manually in the constructor of my workflow to my custom activity, which assigned it in turn to the SendEmail activity. As one doesn't get workflow validation using this approach, it makes for an easy to oversee failure if in a hurry. And additionally, the compiler produces a warning that the correlation token of you SendEmail Activity may be uninitialized.

After a little digging around with Reflector.NET, I finally found out that one can declare a Type Converter of the type CorrelationTokenTypeConverter on the correlation token property of the custom activity. As this type converter is an internal class, the type property of the attribute has to be set by its full qualified class name.

[DefaultValue((string)null),
TypeConverter("System.Workflow.Activities.CorrelationTokenTypeConverter, System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")]
public CorrelationToken WorkflowCorrelationToken
{
get { return (CorrelationToken)base.GetValue(WorkflowCorrelationTokenProperty); }
set
{
base.SetValue(WorkflowCorrelationTokenProperty, value);
sendEmail.CorrelationToken = value;
}
}

(The code snippets above assumes assumes that a “CorrelationToken” dependency property is registered for the custom activity class.)

Now that we can set the correlation token using the designer, we are also able to use a validator class on the custom activity, so the compiler will throw an error if the correlation token is not set. Doing this is quite easy, just add the ActivityValidator attriubte to the activity class definition and implement an activityvalidator class which validates that the correlation token property of the custom activity is set.

[ActivityValidator(typeof(MyActivityValidator))]
public partial class MyActivity : SequenceActivity
{

private class MyActivityValidator : ActivityValidator
{
/// <summary>
/// Verifies that the MyActivity activity is valid.
/// </summary>
/// <param name="manager">The <see cref="T:System.Workflow.ComponentModel.Compiler.ValidationManager"/> associated with validation.</param>
/// <param name="obj">The <see cref="T:System.Workflow.ComponentModel.Activity"/> to be validated.</param>
/// <returns>
/// A <see cref="T:System.Workflow.ComponentModel.Compiler.ValidationErrorCollection"/> object containing any errors or warnings that occurred during validation.
/// </returns>
public override ValidationErrorCollection Validate(ValidationManager manager, object obj)
{
ValidationErrorCollection errors = new ValidationErrorCollection();
MyActivity activity = obj as MyActivity;
if (activity == null)
{
throw new InvalidOperationException();
}
if (activity.Parent != null)
{
if (activity.WorkflowCorrelationToken == null)
{
Hashtable hashtable = activity.GetValue(WorkflowMarkupSerializer.ClrNamespacesProperty) as Hashtable;
if ((hashtable == null) (hashtable["WorkflowCorrelationToken"] == null))
{
errors.Add(ValidationError.GetNotSetValidationError("WorkflowCorrelationToken"));
}
}
}
errors.AddRange(base.Validate(manager, obj));
return errors;
}
}
// SNIP: MyActivity code...
}

07 September 2009

Workflowtasks mit automatischen Erinnerungen

Beispiel Workflow
SharePoint Workflows bieten relativ einfach die Möglichkeit, an verschiedenen Personen Tasks zuzuweisen, welche diese dann abarbeiten. In der Theorie mag sich das zwar gut anhören, in der Praxis werden diese Tasks einfach ignoriert und der Workflow kommt zum Stillstand ("Nööö, ich hab' nie einen Task zugewiesen gekriegt? Ach das E-Mail? Das hab' ich gelöscht…).
Eine Lösung dazu ist simpel: In periodischen Abständen wird dem Benutzer automatisch ein Reminder gesendet. Hört sich auch noch einfach an, gell? Links der Workflow ohne Erinnerungen:


Ein einfacher Approval Workflow also. Wir nehmen mal einfach so an, dass der Genehmigungstask ein Custom Form besitzt, wo der Benutzer zwei Buttons «Genehmigen» und «Ablehnen» hat. Im onApprovalTaskChanged.Invoked Event wird abgefragt, welcher Button geklickt wurde und doSomething führt die entsprechende Aktion aus.


Workflow mit automatischen ErinnerungenFalls wir einen Timeout einbauen möchten, müssen wir auf ein zweites Event warten die Delay Activity um anschliessend den Reminder zu senden. Glücklicherweise gibt's in der Windows Workflow Foundation die Listen Activity, welche es ermöglicht, auf mehrere Events gleichzeitig zu warten. Diese Activity blockiert den Workflow bis einer der angegebenen Events eintritt.
Dort packen wir in einen Ast die OnTaskChanged Activity und in den Anderen eine Delay Activity und eine SendEmail Activity. Da der Reminder nicht nur einmal gesendet werden soll, gibt's noch eine while Schlaufe drumherum.


Vergesst nicht, die Correlation Tokens richtig zusetzten: Es gibt zwei Tokens, eines für die onWorkflowActivated und sendReminder Activities und ein Anderes für die createApprovalTask und onApprovalTaskChanged Activities.

Gut zu wissen: Die Delay Activity wird vom SharePoint Timer Service abgearbeitet. Um sicherzugehen, dass das korrekte Assembly geladen wurde, muss also nach einem Deployment in den GAC auch der Server SPTimerV3 neu gestartet werden. Um zu Debuggen, muss der Prozess OWSTimer.exe attached werden.

28 März 2008

WCM Approval Configrator

Today I wrote a small application which will allow you to set some of the approval workflow settings on a per-site base. This apps will modifiy the workflow association for you on every "Pages" library in the selected sites.

You have the possibility to enable or disable the approval workflow, choose the participants of the workflow and allow or disallow to change the participants lists on workflow start.

I created this application to configure the approval workflow on a customer site. If you want you can download and extend the source code. You will see, that the association data is stored in a XML and with a little debugging you will be able to also modify the other parameters.

Here you can download the application including source code and Visual Studio 2008 project.

Update 10/17/2008: I moved the code to an ASPX, packed as WSP and uploaded to CodePlex. You can find the download on the MOSSApprovalConfig project site.