Custom Workflow Activities

  • April 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Custom Workflow Activities as PDF for free.

More details

  • Words: 6,573
  • Pages: 48
Creating Custom Workflow Activities for SharePoint Server 2007 Using Visual Studio 2008 Summary: Learn how to create a custom activity for Microsoft Office SharePoint Server 2007 to send an e-mail message that has an attachment.

Applies to: Microsoft Office SharePoint Server 2007, Microsoft Visual Studio 2008 Mike Rand, 3Sharp June 2008

In Microsoft Visual Studio 2008, you can create custom activities that can be consumed in workflows. Creating custom activities lets you encapsulate business logic that applies to different scenarios and that can be used in different workflows. This Microsoft Office Visual How To demonstrates how to create a custom activity to send an e-mail message with an attachment.

First, you must create your custom activity. Then, you can add that to a workflow project and use it to send an e-mail message with an attachment. Creating a Custom Activity Project First, create a Visual Studio 2008 Workflow Activity Library project. To create a Visual Studio 2008 Workflow Activity Library project 1.

Open Visual Studio 2008.

2.

On the File menu, point to New, and then click Project.

3.

Under the Workflow Project Type, select the Workflow Activity Library project template.

4.

In the Name box, type SendMailWithAttachmentActivity, and then click OK.

5.

Rename Activity1 to SendMailWithAttachmentActivity.

Coding Custom Activity Now that you have a Custom Activity project, you must add code to send an e-mail message with an attachment. To add code to send an e-mail message with an attachment

1.

The first thing you must do is change your class declaration to inherit directly from Activity instead of SequenceActivity. Open your activity in code view, and change SequenceActivity to Activity. Your class definition should look like the following. C# Copy Code

public partial class SendMailWithAttachmentActivity : Activity { … 2.

Now you must create some Dependency Properties. Add the following fields inside your class definition. C#

Copy Code

public static DependencyProperty ToProperty = DependencyProperty.Register( "To", typeof(string), typeof(SendMailWithAttachmentsTest)); public static DependencyProperty FromProperty = DependencyProperty.Register( "From", typeof(string), typeof(SendMailWithAttachmentsTest)); public static DependencyProperty CCProperty = DependencyProperty.Register( "CC", typeof(string), typeof(SendMailWithAttachmentsTest)); public static DependencyProperty SubjectProperty = DependencyProperty.Register( "Subject", typeof(string), typeof(SendMailWithAttachmentsTest)); public static DependencyProperty BodyProperty = DependencyProperty.Register( "Body", typeof(string), typeof(SendMailWithAttachmentsTest)); public static DependencyProperty AttachmentProperty = DependencyProperty.Register( "Attachment", typeof(string), typeof(SendMailWithAttachmentsTest)); public static DependencyProperty SmtpServerProperty = DependencyProperty.Register( "SmtpServer", typeof(string), typeof(SendMailWithAttachmentsTest)); public static DependencyProperty InvokeEvent = DependencyProperty.Register(

"Invoke", typeof(EventHandler), typeof(SendMailWithAttachmentsTest)); Notice that the last field, InvokeEvent, is of type EventHandler. This enables you to add custom code to your activity when it is used in a workflow. 3.

Now, you must add properties for your fields. Add the following code under the fields you just added. C# Copy Code

[DesignerSerializationVisibility(DesignerSerializationVisibility. Visible)] [ValidationOption(ValidationOption.Required)] [Browsable(true)] [Description("Enter any e-mail recipients, separated by semicolons")] public string To { get { return ((string)(base.GetValue(SendMailWithAttachmentsTest.ToProperty))); } set { base.SetValue(SendMailWithAttachmentsTest.ToProperty, value); } } [DesignerSerializationVisibility(DesignerSerializationVisibili ty.Visible)] [ValidationOption(ValidationOption.Required)] [Browsable(true)] [Description("Enter the e-mail sender")] public string From { get { return ((string)(base.GetValue(SendMailWithAttachmentsTest.FromProperty))); } set { base.SetValue(SendMailWithAttachmentsTest.FromProperty, value); } } [DesignerSerializationVisibility(DesignerSerializationVisibilit y.Visible)] [ValidationOption(ValidationOption.Optional)]

[Browsable(true)] [Description("Enter any carbon copy recipients, separated by semicolons")] public string CC { get { return ((string)(base.GetValue(SendMailWithAttachmentsTest.CCProperty))); } set { base.SetValue(SendMailWithAttachmentsTest.CCProperty, value); } } [DesignerSerializationVisibility(DesignerSerializationVisibility .Visible)] [ValidationOption(ValidationOption.Required)] [Browsable(true)] [Description("Enter the e-mail subject")] public string Subject { get { return ((string)(base.GetValue(SendMailWithAttachmentsTest.SubjectProperty) )); } set { base.SetValue(SendMailWithAttachmentsTest.SubjectProperty, value); } } [DesignerSerializationVisibility(DesignerSerializationVisibilit y.Visible)] [ValidationOption(ValidationOption.Optional)] [Browsable(true)] [Description("Enter the body text of the e-mail")] public string Body { get { return ((string)(base.GetValue(SendMailWithAttachmentsTest.BodyProperty))); } set { base.SetValue(SendMailWithAttachmentsTest.BodyProperty, value); } }

[DesignerSerializationVisibility(DesignerSerializationVisibilit y.Visible)] [ValidationOption(ValidationOption.Optional)] [Browsable(true)] [Description("Enter an attachment file path")] public string Attachment { get { return ((string)(base.GetValue (SendMailWithAttachmentsTest.AttachmentProperty))); } set { base.SetValue(SendMailWithAttachmentsTest.AttachmentProperty, value); } } [DesignerSerializationVisibility(DesignerSerializationVisibilit y.Visible)] [ValidationOption(ValidationOption.Required)] [Browsable(true)] [Description("Enter the Smtp Server for the email")] [DisplayName("Smtp Server")] public string SmtpServer { get { return ((string)(base.GetValue (SendMailWithAttachmentsTest.SmtpServerProperty))); } set { base.SetValue(SendMailWithAttachmentsTest.SmtpServerProperty, value); } }

4.

Now, you must add a property for your InvokeEvent field. This EventHandler property lets you add code in a workflow to interact with this activity programmatically. Add this code under the Properties you just added. C# Copy Code

[DescriptionAttribute("Invoke")] [CategoryAttribute("Invoke Category")] [BrowsableAttribute(true)] [DesignerSerializationVisibilityAttribute(DesignerSerializationVisib ility.Visible)] public event EventHandler Invoke

{ add { base.AddHandler(SendMailWithAttachmentsTest.InvokeEvent, value); } remove { base.RemoveHandler(SendMailWithAttachmentsTest.InvokeEvent, value); } }

5.

Add a using statement at the top of the class. This enables you to access the ASP.NET 2.0 Mail namespace for sending your e-mail message. Add the following code. C# Copy Code

using System.Net.Mail;

6.

The last thing you must do here is override the Execute method. Add the following method inside your class definition. C# Copy Code

Protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { // Raise Invoke Event to execute custom code in the workflow. this.RaiseEvent(SendMailWithAttachmentsTest.InvokeEvent, this, EventArgs.Empty); // Set reference to Smtp Server. SmtpClient smtp = new SmtpClient(SmtpServer); // Create mail message. MailMessage msg = new MailMessage(); msg.To.Add(To); msg.From = new MailAddress(From); if (!String.IsNullOrEmpty(CC)) {

msg.CC.Add(CC); } if (!String.IsNullOrEmpty(Subject)) { msg.Subject = Subject; } if (!String.IsNullOrEmpty(Body)) { msg.Body = Body; } if (!String.IsNullOrEmpty(Attachment)) { msg.Attachments.Add(new Attachment(Attachment)); } // Send the e-mail. smtp.Send(msg); // Indicate that the activity has completed. return ActivityExecutionStatus.Closed; } Installing a Custom Activity Before you can use your custom activity, you must install it in the global assembly cache (GAC). For an assembly to be installed in the GAC, you must give it a strong name. To install the custom activity to the GAC

1.

First, give your assembly a strong name. In Solution Explorer, right-click the project, and then select Properties.

2.

Select the Signing tab.

3.

Select the Sign the assembly check box.

4.

In the Choose a strong name key file list, select New.

5.

In the Key file name text box, type Key.

6.

In this demonstration, we are not concerned with security, so clear the Protect my key file with a password check box. Click OK. Now your assembly is strong named, and all you have to do is install it to the global assembly cache.

7.

Save and build the project.

8.

Open a Visual Studio 2008 command prompt.

9.

Navigate to the Activity solution directory, and run the following command: gacutil /if SendMailWithAttachmentActivity.dll

Now, that you have successfully installed your activity, you can use it from a workflow project. Creating a Workflow Project

Next, you create a Sequential Workflow project to use your custom activity. To create a Visual Studio 2008 Sequential Workflow project 1.

Start Visual Studio 2008.

2.

On the File menu, point to New, and then click Project.

3.

Under the Office Project Type, select the SharePoint 2007 Sequential Workflow project template.

4.

In the Name box, type SendEmailWithAttachmentWF. Click OK.

5.

Type a valid SharePoint Web URL. The example uses http://moss.litware.com. Click Next.

6.

Select a library or list to associate with your workflow, and click Next.

7.

Leave the default options for how a workflow can be started, Manually by users and When an Item is created. Click Finish.

Adding a Custom Activity to the Toolbox Now that you have created your Sequential Workflow project, you must add your custom activity to your Toolbox before you can use it. To add the custom activity to the Visual Studio 2008 Toolbox

1.

On the Tools menu, select Toolbox items.

2.

Select the Activities tab.

3.

Click Browse, and browse to the SendMailWithAttachmentActivity.dll in your Activity solution directory. Click Open.

4.

Click OK.

5.

Your activity is now available in the Toolbox. Figure 1. Toolbox with new activity available

Note: If you have a toolbox category selected, the activity is added to that category by default. You can drag the activity to another category if you want. Adding a Custom Activity to the Workflow Now, you must add your custom activity to your simple workflow. To add the custom activity to the workflow

1.

From the Toolbox, drag the SendMailWithAttachmentActivity to be under the onWorkflowActivated1 activity.

2.

Open the Properties window, and rename it to sendMailWithAttachmentActivity.

3.

You can set the activity properties from within the Properties window. Instead, you will do that in code. Select the Event view in the Properties window.

4.

You should see a single event, Invoke. Double-click this property. Figure 2. Properties window

This takes you to the code-behind class, and you will see that a method stub has been autogenerated for you. 5.

Add the following code inside this method. C# Copy Code

SendMailWithAttachmentActivity.To = "[email protected]"; SendMailWithAttachmentActivity.From = "[email protected]"; SendMailWithAttachmentActivity.CC = "[email protected]"; SendMailWithAttachmentActivity.Subject = "Email with Attachment Testing."; SendMailWithAttachmentActivity.Body = "This email should have an attachment."; SendMailWithAttachmentActivity.Attachment = @"C:\Documents and Settings\Administrator\Desktop\code snippets.txt"; SendMailWithAttachmentActivity.SmtpServer = workflowProperties.Site.WebApplication.OutboundMailServiceInst ance.Server.Address; 6. Note: The purpose of this demonstration is to show you how to create and consume a custom activity. In a real-world scenario, you would never hard-code these values. You would retrieve them programmatically, or possibly through an Initiation form or a Task form. Running the Workflow Project from Visual Studio 2008 Press F5 to run your workflow. When you activate this workflow on a document in a document library, an e-mail message is generated and sent with the attachment you specified. Figure 3. E-mail message with attachment

1. Introducing Office SharePoint Designer 2007 Workflows Office SharePoint Designer 2007, a replacement for FrontPage, is used as an aid in the rapid design and deployment of workflows. Office SharePoint Designer 2007 is specifically designed to help create and customize web sites and workflows built with SharePoint Products and Technologies. The Development process in SharePoint Designer is based on declarative rules-based, code-free workflow editor. SharePoint Designer (SPD) gives list administrators, business administrators, and designers the ability to create workflows without writing any code. SPD exposes many of the workflow activities that ship with SharePoint as "actions" that users can string together into a sequential process. These actions are customized via sentences that describe the action and bind data to action parameters. However, businesses will oftentimes need more custom functionality than the actions provided with SharePoint, requiring them to write custom code that can run on the server. This guide describes how to write a custom code as an activity using the Visual Studio Extensions for Windows Workflow Foundation and expose it as an action in SPD. "Activity" refers to the basic building block of functionality in a Windows Workflow Foundation (WF) workflow.

In Office SharePoint Designer 2007, however, each activity appears as an action, represented by a sentence that contains variables that the user can configure using drop-down menus and lookup dialog boxes. Users can also select conditions, which are configurable conditional clauses that direct the flow of the workflow. As the user is selecting and configuring conditions and actions in the workflow interface, Office SharePoint Designer 2007 generates the two files that actually represent the workflow class: The workflow markup file, which contains markup language that describes the activities included in the workflow. The workflow rules file contains the business logic of the workflow in declarative rules form, rather than as code.

2. Create a Microsoft Office InfoPath 2007 Form 1. Create a new Microsoft Office InfoPath 2007 Form. 2. Add two Text boxes and rename the text boxes as "Contributors" and "Readers". 3. Save the Form.

4. Publish the form with the two columns to the Microsoft Office SharePoint Server 2007 site for which the item level security needs to be implemented.

3. Create a custom activity in Visual Studio with promoted properties 1. Navigate to Start | All Programs | Microsoft Visual Studio 2005 | Microsoft Visual Studio 2005. 2. Select the File | New | Project menu command. 3. Visual Studio displays the New Project dialog box. 4. Select the Visual C# | Workflow project type. 5. Select the Workflow Activity Library template. 6. Enter the path in the Location field.

7. Enter the name in the Name field. 8. Click OK.

9. Visual Studio creates the activity library project, including a single activity, Activity1, and displays a design view of Activity1.cs.

10. Rename Activity1.cs to ItemLevelSecurityActivity.cs by right clicking on Activity1.cs and choosing rename. 11. Select the View | Toolbox menu command to open the Toolbox window.

12. From the Toolbox window, drag a Code activity and drop it onto the "Drop Activities Here" work area of ItemLevelSecurityActivity's design view. 13. The Activity Designer displays a code icon in the work area.

14. Rename CodeActivity1 to ItemLevelSecuritycodeActivity by right clicking on CodeActivity1 and choosing Properties and change the Name Property.

15. In the Solution Explorer, right click on References to bring up the context menu 16. Select Add Reference.

17. From the Add Reference dialog box, add references to the Windows SharePoint Services and the Windows SharePoint Services WorkflowActions.

18. In the Solution Explorer, right click on ItemLevelSecurityActivity.cs to bring up the context menu.

19. Select View Code. 20. Add the following namespaces in the code: Collapse

Copy Code

using Microsoft.SharePoint; using Microsoft.SharePoint.Workflow; using Microsoft.SharePoint.WorkflowActions;

Note: The activity wouldn't be useful if it didn't pass information on, so to make it available to the rest of the workflow, we will need to use property promotion. Property promotion consists of getters and setters to allow the property to be bound to variables outside of the activity. For this example, we need to derive the Workflow Context object to retrieve the current SharePoint Site, the List Id for which the activity is attached and the current List Item to provide Item Level Security. 21. Place the cursor on the closing bracket of the ItemLevelSecurityActivity constructor and press Enter Twice. 22. Right Click on the last line you just inserted.

23. Select Insert Snippet.

24. Select Workflow.

25. Select DependencyProperty - Property.

This code snippet generates the getter/setter code and allows you to specify the property name, type and description for the property.

26. Fill in these fields in the boilerplate code with the corresponding values. Use Tab to move between the fields and press enter when finished with the fields.

a. For deriving the Workflow Context object to retrieve the current SharePoint Site:

i. Name: __Context. ii. Type: WorkflowContext. iii. Description: Context. b. For retrieving the List Id for which the activity is attached:

i. Name: ListId ii. Type: string iii. Description: List Id c. For retrieving the current List Item to provide Item Level Security:

i. Name: ListItem ii. Type: int iii. Description: ListItem Note: Remove the Category Property and add the following code in its place for all the three dependency properties. [ValidationOption(ValidationOption.Required)] The resulting output should resemble the following:

With this customized, the property is exposed to the rest of the workflow. The workflow can now bind variables to these properties for both input and output. 27. In the Solution Explorer, right click on References to bring up the context menu 28. Select Add Reference. 29. From the Add Reference dialog box, add references to the System.DirectoryServices.

30. In the Solution Explorer, right click on ItemLevelSecurityActivity.cs to bring up the context menu.

31. Select View Code. 32. Add the following namespaces in the code: Collapse

Copy Code

using System.DirectoryServices;

33. In the Solution Explorer, right click on ItemLevelSecurityActivity.cs to bring up the context menu.

34. Select View Designer 35. Double click the ItemLevelSecuritycodeActivity activity to view the ItemLevelSecuritycodeActivity _ExecuteCode method and write the custom code behind your activity for implementing the Item Level Security as displayed.

36. In the Solution Explorer, Right Click on Properties and choose Open from the context menu.

37. Navigate to the Signing tab.

38. Check the Option Sign the Assembly. 39. Select the New option from the Drop down below 40. In the Create Strong Name Key dialog box, enter the Key File Name 41. Uncheck the Protect my key file with a password option. 42. Select the Build | Build Solution menu command.

4. Deploy the dll to the GAC and add it to the web.config file The next step is to compile your activity and deploy it to the GAC (C:\WINDOWS\assembly). The assembly must be signed. You can drag and drop this into the GAC directory or use the .net gacutil tool. Keep a note of the assembly, class, version, and public key token, as they'll be used later on in the .ACTIONS file. 1. Navigate to the root port directory of the SharePoint Site for which the activity is created located in "C:\inetpub\wwwroot\wss\virtualdirectories" and search for "web.config" file. These xml files contain lists of authorized types that can be used for that server port.

2. Open the file and search for "WorkflowActions", which should take you to an entry that looks like this:

Collapse

Copy Code



Underneath this tag, add a corresponding tag for your dll. For example: Collapse

Copy Code



The activity dll is now ready to be run on the server

5. Edit the WSS.ACTIONS file to describe the activity parameters The final step of preparing an activity for SPD is to change the WSS.ACTIONS file. This xml file describes the types of the promoted properties of the activity and how to map them into a rules sentence. 1. Navigate to "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\Workflow" folder and open the WSS.ACTIONS file. 2. Navigate to the end of the file. 3. Append the following code before the tag.

Collapse

Copy Code

<Parameters> <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" Direction="In"/> <Parameter Name="ListId" Type="System.String, mscorlib" Direction="In" /> <Parameter Name="ListItem" Type="System.Int32, mscorlib"

Direction="In" />


Note: The "Action" tag defines basic information about the action with the following attributes: � Name � name of the action (this is what SPD displays in its actions list) � ClassName � the name of the activity, i.e. Namespace.WorkflowClassName � Assembly � details of the GAC'ed assembly � AppliesTo � describes what types of lists this activity can be used for, either "list", "doclib", or "all" � Category � category that SPD will display in the categories for available actions

RuleDesigner Collapse

Copy Code



The next section is the "RuleDesigner" section. This describes a rule sentence for the action as well as how to bind them to the activity properties. These are the sentences SPD displays in its rules wizard. The variable parameters in the sentence, e.g. %1, etc., are exposed as customization links. When displayed, they will be replaced with the "FieldBind" tags below, where %1 will be replaced with the FieldBind with Id=1,etc. The "FieldBind" tag describes each variable parameter. The "Field" attribute corresponds to the parameter, or activity property, as it is described in the Parameter tag in the markup. "DesignerType" describes what type of interface to show when the user clicks on the link. For example, if you want to show a select user dialog, you would use "SinglePerson" for the designer type. The "Text" attribute is how the field is displayed in the sentence.

The end result for the above markup would look something like this in SPD:

Parameters Collapse

Copy Code

<Parameters> <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" Direction="In"/> <Parameter Name="ListId" Type="System.String, mscorlib" Direction="In" /> <Parameter Name="ListItem" Type="System.Int32, mscorlib" Direction="In" />

Finally, the "Parameters" tag tells the RuleDesigner how to map the fields to the promoted properties on the workflow activity. Each "Parameter" describes the name of the property (which should match the corresponding FieldBind above), the system type of the property, and direction ("In" means that the activity gets that parameter, and "Out" means the activity sets that parameter). Once you have this file laid out, save your file.

6. Boot SPD 1. Do an iisreset.

2. Navigate to Start | All Programs | Microsoft Office | Microsoft Office SharePoint Designer 2007.

3. Select the File | New | Workflow menu command.

4. In the Workflow Designer dialog box, enter a name for the Workflow and select the SharePoint Document library list for which the activity should be attached from the Dropdown.

5. Check the Automatically start this workflow when a new item is created option. 6. Check the Automatically start this workflow whenever an item is changed option. 7. Click Next. 8. Click Actions

9. Select the More Actions 10. In the Workflow Actions dialog box, click the dropdown for the Select a Category and choose Extras.

11. In the Choose an Action box, select the Item Level Security activity in sharepoint designer will appear and click Add. 12. Note that Apply security to this Document Library is displayed.

13. Click on this option in the Actions 14. From the Choose List Item dialog box, Select the Current Item option and click OK

15. Now the Actions is changed by displaying the current item's name.

16. Click Finish. 17. The Workflow can now be checked by creating a new InfoPath form, by entering the Authors and Readers fields. 18. Save the InfoPath form to the SharePoint site.

19. Select Manage Permissions from the Context Menu of the item saved and check for the permissions.

7. Conclusion Though this topic covers implementing Item Level Security by creating custom activity, the task can also be achieved by creating Item_Saved and Item_Updated Event Handlers for Lists. Though there are multiple ways of implementing the task, creating custom activity is more effective by means of reusability and lesser coding in VS 2005.

Add custom workflow activities to SharePoint Designer (Part 1) Without a doubts one of the best things of MOSS 2007 is the new SharePoint Designer, and within him, the workflow designer, that allows us speedy and simple form to design workflows. As I have commented in other occasions, if we wish to make more complex workflows, or state machines, we need to use Visual Studio. SharePoint Designer, allows us to make sequential workflows with predetermined activities. Nevertheless, the possibility to extend the basic activities exists and we can extend the functionality of ours workflows without to write them completely in Visual Studio. Out-the-box, SharePoint Designer includes 22 actions.

Those actions are defined in the file WSS.ACTIONS, that resides in the directory “C:\Program Files\Common files\Microsoft Shared \web server extensions\12\1033\TEMPLAT\Workflow”. In this file, the conditions and the actions that appear within SharePoint Designer are defined. <Parameters> <Parameter Name="_1_" Type="System.DateTime, mscorlib" Direction="In"/> <Parameter Name="_2_" Type="System.DateTime, mscorlib" Direction="In"/> Herein, we can see the assembled dll that handles the condition, to which elements he is applied, and if it is possible to use the present item in the workflow.

Within the condition we have the rule for the designer, with the text that is going to appear; each rule uses a series of fields tags FieldBind, that connects with the necessary parameters in the assembled file. Each tag FieldBind has an identifier that corresponds with the position of the field within sentence ID=1, and that will be %1 in the sentence attribute as well. Also we can see attributes like Text, that will be the text by defect, and the DesignerType, that is the type of field. After that, we have the section of Parameters with the different parameters that will go to the assembled file. The Name attribute has to correspond with the Field attribute of tag FieldBind, and the direction of the parameter needs to be In for input and Out for output. <Parameters> <Parameter Name="ModerationStatus" Type="System.String, mscorlib" Direction="In" /> <Parameter Name="Comments" Type="System.String, mscorlib" Direction="Optional" /> <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" /> <Parameter Name="__ListId" Type="System.String, mscorlib" Direction="In" /> <Parameter Name="__ListItem" Type="System.Int32, mscorlib" Direction="In" /> Now, we are going to see how the actions look in the same file; they are very similar to the conditions.

The first part includes the assembled one that will take care to handle the action. The second one, are the rules for the designer. In this case the fields that has been used are a

combobox (DesignerType= " Dropdown ") and a line of text (DesignerType= " TextArea ") The third part of the parameters, besides to use both fields defined in the rule of the designer, uses three additional parameters that are: __Context: that it is the context of the WorkFlow. __ListId: you go of the list with which we are working __ListItem: the present item With these three fields (that they are pre-established, so that we can use them whenever we want) we have as much control on the list as on the job stream that is being carried out.

At the moment A file XSD for this type of archives does not exist Add custom workflow activities to SharePoint Designer (Part 2) In order to add a new activity to our SharePoint Designer, first we need to begin a WorkFlow project in Visual Studio 2005, concretely, a Workflow Activity Library (Workflow activity library).

From this point we would create our activity; for this example I am going to create an activity that will send a text to the event viewer. 1:

public partial class LogEventViewer : Activity

2:

{

3: 4:

public static DependencyProperty TextLogProperty =

5:

DependencyProperty.Register("TextLog", typeof(string), typeof(LogEventViewer));

6: 7:

public LogEventViewer()

8:

{

9: 10:

InitializeComponent(); }

11: 12:

/// <summary>

13:

/// Valor que figurará en el visor de eventos

14:

///

15:

/// Texto

16:

[Description("Texto que saldrá en el visor de eventos")]

17:

[Category("User")]

18:

[Browsable(true)]

19:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

20:

public string TextLog

21:

{

22:

get { return (string) GetValue(TextLogProperty); }

23:

set { SetValue(TextLogProperty, value); }

24:

}

25: 26:

/// <summary>

27:

/// Ejecución de la actividad

28:

///

29:

/// <param name="provider">Contexto de ejecución de la actividad

30:

///

31:

protected override ActivityExecutionStatus Execute(ActivityExecutionContext provider)

32:

{

33: 34:

EventLog eventLog = new EventLog("Workflow");

35:

eventLog.Source = "SharePoint Workflow";

36: 37:

try

38:

{

39:

eventLog.WriteEntry(TextLog, EventLogEntryType.Information);

40:

}

41:

finally

42:

{

43:

eventLog.Dispose();

44:

}

45: return ActivityExecutionStatus.Closed;

46: 47: 48:

} }

First, we declare a dependent property of the workflow called TextLogProperty, which we will use to pass the text that we wish to show in the event viewer. The internal property of the activity will be TextLog; this internal property obtains and establishes the value from the dependent property of the workflow. Then we define the Execute method, that will be the method in charge to visualize the message in the event viewer. A good practice is that the activities include a Validador, that I have omitted in the example but that is highly recommended although not obligatory, or if we want to use the activity inside of the visual studio workflow designer. Once we have made the compilation, we can test it first (another good practice) creating an application to host the workflow and checking the activity. Finally, after we are sure that our activity works correctly, we must install it in the GAC in our SharePoint server. And we need to modify the Web.config to include our assembly in the following section: <System.Workflow.ComponentModel.WorkflowCompiler>

......


Namespace="IdeSeg.SharePoint.Workflow.Activities" TypeName="*" Authorized="True" / rel="nofollow">
Now we need to modify the file WSS.ACTIONS that we saw in the first article in order to add our new action <Parameters> <Parameter Name="TextLog" Type="System.String, mscorlib" Direction="In" /> What we have done in the first place is authorize our assembly so that he is now an integral part of the WorkFlow engine of SharePoint, and secondly, adding it to the WSS.ACTIONS file, we have indicated to the SharePoint Designer that we have added a new activity. When we use SharePoint Designer to publish a site, at the moment that we created a new workflow or we published an existing one, he communicates with SharePoint and recovers the File WSS.ACTIONS to configurate the assistant of the WorkFlow. In this way the new actions will be part of the file XOML that the SharePoint Designer will create. Finally the result within the SharePoint Designer will be as follow:

Creating your own Custom Workflow Activities as Components using Windows Workflow Foundation (Framework 3.0) and deployment on SharePoint 2007. Required Installation Setup •

Visual Studio .Net 2005



Framework 3.0



Windows Workflow Foundation Extension for Workflow Activity Template



SharePoint Portal 2007,SharePoint Services and Microsoft Office SharePoint Designer

The steps to add a simple activity to the SharePoint Designer interface include: 1. Create a custom activity assembly. 2. Sign and deploy the activity assembly to the GAC. 3. Configure SharePoint to recognize the custom activity.

4. Create a .ACTIONS file to be used by SharePoint Designer. Step 1: Create a custom activity assembly •

Open Visual Studio 2005 solution.



Select New Project and Workflow Activity Library Template which is a project for creating a library of activities which can later be reused as building blocks in workflows.

Code Block using /> using using using using

System;
using System.Workflow.ComponentModel.Compiler; using System.Workflow.ComponentModel.Serialization; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.Runtime; using System.Workflow.Activities; using System.Workflow.Activities.Rules; using System.Collections.Generic; using System.Text; namespace ActivityLibrary1 { public partial class ADComponent : System.Workflow.ComponentModel.Activity { private string cn; public ADComponent() { InitializeComponent(); } public static DependencyProperty DirectoryUriProperty = DependencyProperty. Register"DirectoryUri",typeofSystem.String),typeo(ActivityLibrary1.ADComponent)); [DescriptionAttribute("Please specify the URI of the directory. Either an AD Server or an XML File.")] [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)] [ValidationOption(ValidationOption.Required)] [BrowsableAttribute(true)] [Category("Directory")] public string DirectoryUri { get { return ((String)(base.GetValue(ADComponent.DirectoryUriProperty))); } set { base.SetValue(ADComponent.DirectoryUriProperty, value); } } public static DependencyProperty QueryProperty = DependencyProperty.Register ("Query", typeof(System.String), typeof(ActivityLibrary1.ADComponent)); [DescriptionAttribute("Please specify the Username of the user to retrieve.")] [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)] [ValidationOption(ValidationOption.Optional)] [BrowsableAttribute(true)] [Category("Query")] public string Query { get { return ((String)(base.GetValue(ADComponent.QueryProperty))); } set { base.SetValue(ADComponent.QueryProperty, value);

}

} } public static DependencyProperty RetrievedUserDataProperty = Dependency Property.Register ("RetrievedUserData", typeof(System.String), typeof (ActivityLibrary1.ADComponent)); [DescriptionAttribute("Please specify the Username of the user to retrieve.")] [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)] [ValidationOption(ValidationOption.Optional)] [BrowsableAttribute(true)] [Category("RetrievedUserData")] public string RetrievedUserData { get { return ((String)(base.GetValue(ADComponent.RetrievedUserDataProperty))); } set { base.SetValue(ADComponent.RetrievedUserDataProperty, value); } } public string CN { get { return cn; } set { cn = value; } } protected override ActivityExecutionStatus Execute(ActivityExecutionContext context) { string a = "ActiveDirectory"; switch (a) { case "ActiveDirectory": ADHelper adh = new ADHelper(this.DirectoryUri); CN = adh.FetchUser(this.Query); break; } //Set the results property this.RetrievedUserData = CN; return ActivityExecutionStatus.Closed; }

} Code Bock For Supportive ADHelper Class //-----------------------------------------------------------------------------//

//--------------Active Directory helper Class----(Rifaqat:2nd April 06)-------// //-------Description: ...............................................--------// //-------------------------------------------------------------------------// using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.DirectoryServices; using System.Collections; namespace ActivityLibrary1 { internal class ADHelper { private string ldapPath; DirectorySearcher search; internal ADHelper(string ldapPath) { this.ldapPath = ldapPath; search = new DirectorySearcher(new DirectoryEntry(ldapPath)); } internal string GetUsersManager(string loginName) { SearchResult result; search.Filter = String.Format("(SAMAccountName={0})", loginName); search.PropertiesToLoad.Add("manager"); result = search.FindOne(); if (result == null) { return ""; } else { string userPath = result.Properties["manager"][0].ToString(); System.DirectoryServices.DirectoryEntry de = new DirectoryEntry("LDAP://" + userPath); return de.Properties["sAMAccountName"].Value.ToString(); } } internal string FetchUser(string Designation) { string _User = ""; try { SearchResult result; search.Filter = String.Format("(Title={0})", Designation); search.PropertiesToLoad.Add("cn"); result = search.FindOne(); if (result != null) { _User = result.Properties["cn"][0].ToString();

} } catch (Exception ex) { } return _User; } internal string FetchUseronDesg(string loginName) { string _User = ""; try { SearchResult result; search.Filter = String.Format("(SAMAccountName={0})", loginName); search.PropertiesToLoad.Add("title"); search.PropertiesToLoad.Add("cn"); result = search.FindOne(); if (result != null) { _User = result.Properties["title"][0].ToString(); } } catch (Exception ex) { string s = ex.Message; } return _User; } }

}

Your Solution Explorer will be like this:

In this code the DirectoryUri and Query are passing as inputproperty and are used to specify the text that will be displayed in the Display Name of User as Output. We use a dependency property to enable the workflow to bind data to it. As with all workflow activities, the Execute method performs the action.

Step 2: Sign and deploy the activity assembly to the GAC Step 3: Configure SharePoint to recognize the custom activity After you build the custom activity assembly, sign it and copy it to the GAC. You then have to tell SharePoint to trust the assembly. This is similar to configuring a web part as a safe control, but instead of adding an entry to the <SafeControls> section, you add an entry to the <System.Workflow.ComponentModel.WorkflowCompiler> section. Edit the web.config file for your SharePoint web application and add an element as in the following example: •

Goto in your Site using this URL C:\Inetpub\wwwroot\wss\VirtualDirectories\10161



Open your Config File.



You need to add your assembly in specific site port config file:

Step 4: Create a .ACTIONS file to be used by SharePoint Designer • The final step is to create the .ACTIONS file that describes the activity to SharePoint Designer. Since this is an XML file, you can create it using Visual Studio or any XML editor. • This file describes the public properties exposed by the activity and tells SharePoint Designer how to map those properties into rules that can be displayed to the user. The following code shows a custom .ACTIONS file for the custom Active Directory activity. • Goto this path for .Actions File C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\Workflow <WorkflowInfo> <Parameters> <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions. WorkflowContext, Microsoft.SharePoint.WorkflowActions" Direction="In" />

<Parameter Name="ContentTypeId" Type="System.String, mscorlib"Direction="In" /> <Parameter Name="AssignedTo" Type="System.String, mscorlib" Direction="In" /> <Parameter Name="Title" Type="System.String, mscorlib" Direction="In" /> <Parameter Name="TaskId" Type="System.Int32, mscorlib" Direction="Out" />
• The Actions tag tells SharePoint Designer what to display for each action in the set. Within that, the Action tag describes the individual action. The Name attribute is what gets displayed in the designer. The ClassName and Assembly attributes are used in the generated XAML for the workflow. The interesting part is the way the RuleDesigner and Parameter tags work. The RuleDesigner tag lets you set up a sentence that gets displayed in the designer as you build up the workflow. The Sentence attribute allows you to bind to the activity properties and then substitute their values when the activity is executed. • You can declare as many actions as you want in the file. A good rule of thumb is to use a separate .ACTIONS file for each logical group of custom activities you wish to deploy. Once you've created your .ACTIONS file and copied it to the server, you can refresh the site in SharePoint Designer and your custom activity will appear in the workflow designer as shown below.

Site Definition in SharePoint By Dhananjay Kumar January 08, 2009 This article will explain about Site Definition, why we do need custom site definition ?and how to create and deploy a custom site definition.

Site Definition •

Site Definitions are the foundations on which all sites and user templates are built.



Site Definition is collection ox XML and .aspx file.



Site Definitions are predefined components needs to be included when a site was created in SharePoint server.



Site Definition contains information of Web Part , Lists, Features and navigation bars to be included in the site.



Customizing Portal Sites and other SharePoint sites using Site Definition is most appropriate for third party developer and SharePoint Administrator.



Site Definitions requires access to a file system of the Web Server.



Server administrator must be also involved in deployment of Site Definitions.



Custom Site Definitions are Version and Upgrade independent.



Subsequent upgrades to SharePoint products and technologies may overwrite existing Site Definitions. Using Custom Site definition exclude site from potential upgrade issues.



To avoid Unghosting , Custom Site Definition is to be create.



There are two options to create it

1. Create New Site Definition File : Either Start from Scratch and create files one by one or Copy an existing Site Definition and modify it.

2. Copy a Site Definition and change it in Visual Studio: We can make copy an existing site definition and modify it in visual studio to create new site definition.



The configuration of this site definitions are defined in XML file which is available in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\XML folder.



In the file system these definitions are available in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\Site Templates.



Each of these site definitions consists a XML folder and a Home page (default.aspx).

Steps to create custom Site Definition 1. Log on as an administrator

2. Browse to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates. Copy STS folder-> Paste it at same place -> Rename it as TIGER. 3. Open the folder Tiger 4. Search for default.aspx 5. Open default.aspx in notepad. 6. Modify code. Here we need to add code for site definition. Default.aspx <%@ Page language="C#" MasterPageFile="~masterurl/default.master" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=12 .0.0.0,Culture=neutral,P ublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <SharePoint:EncodedLiteral runat="server" text="<%$Resources:wss,multipages_homelink_text%>" EncodeMethod="HtmlEncode"/> - <SharePoint:ProjectProperty Property="Title" runat="server"/>

<style type="text/css"> TD.ms-titleareaframe, .ms-pagetitleareaframe { height: 10px; } Div.ms-titleareaframe { height: 100%; } .ms-pagetitleareaframe table { background: none; height: 10px; } <META Name="CollaborationServer" Content="SharePoint Team Web Site"> <script type="text/javascript"> var navBarHelpOverrideKey = "wssmain"; <SharePoint:DelegateControl runat="server" ControlId="SmallSearchInputBox" />

<style type="text/css"> .ms-bodyareaframe { padding: 0px; }
<SharePoint:ProjectProperty Property="Description" runat="server"/>
<WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Top" Title="loc:Top" />
<WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Left" Title="loc:Left" />     <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Right" Title="loc:Right" />    
<WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Bottom" Title="loc:Bottom" />

7. Register new site definition to SharePoint. 8. Open the folder C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\XML 9. Copy the file WEBTEMP.XML and save it as WEBTEMPTIGER.xml. here make a note that , we need to append name of folder which we created in step 2 ( in this case it is tiger) to WEBTEMP. So here name would be WEBTEMPTIGER.xml 10. Open WEBTEMPTIGER.XML in notepad and replace it with following content.

Make sure here ID should be greater than 10000. It must not collide with id of any other Site Definition. 11. Restart IIS. Go to Start->Run->IISRESET 12. Now you would be able to see this Site Definition inside Custom category.

Related Documents

Workflow
October 2019 32
Workflow
November 2019 32
Custom
June 2020 22
Activities
May 2020 31