Export (0) Print
Expand All
Expand Minimize

Creating Custom Workflow Activities for SharePoint Server 2007 Using Visual Studio 2008

SharePoint 2007

Summary:  Learn how to create a custom activity for Microsoft Office SharePoint Server 2007 to send an e-mail message that has an attachment.

Office Visual How To

Applies to:  Microsoft Office SharePoint Server 2007, Microsoft Visual Studio 2008

Mike Rand, 3Sharp

June 2008

Overview

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.

Code It

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.

    public partial class SendMailWithAttachmentActivity : Activity
    { …
    
  2. Now you must create some Dependency Properties. Add the following fields inside your class definition.

        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.

       [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(DesignerSerializationVisibility.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(DesignerSerializationVisibility.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(DesignerSerializationVisibility.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(DesignerSerializationVisibility.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(DesignerSerializationVisibility.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.

       [DescriptionAttribute("Invoke")]
       [CategoryAttribute("Invoke Category")]
       [BrowsableAttribute(true)]
    [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.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.

    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.

        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

    Toolbox with activity available
    Cc627284.note(en-us,office.12).gifNote:
    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

    Properties window

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

  5. Add the following code inside this method.

        SendMailWithAttachmentActivity.To = "nicolec@litwareinc.com";
        SendMailWithAttachmentActivity.From = "willisj@litwareinc.com";
        SendMailWithAttachmentActivity.CC = "willisj@litwareinc.com";
        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.OutboundMailServiceInstance.Server.Address;
    
Cc627284.note(en-us,office.12).gifNote:
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

E-mail with attachment

Read It

This Microsoft Office Visual How-To demonstrates how to create a simple custom activity. Custom activities enable you to encapsulate business logic in an efficient, reusable manner. You can update this custom activity to include validation, toolbox designer graphics, and the ability to include more than a single attachment.

See It

Creating a Workflow Activity for SharePoint Server

Watch the Video

Video Length: 00:09:06

File Size: 8.19 MB WMV

Explore It

Community Additions

ADD
Show:
© 2014 Microsoft