SharePoint SendEmail Activity “Go to My Tasks”


In Microsoft.SharePoint.WorkflowActions.SendEMail Acitivity, there is a property called IncludeStatus http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.workflowactions.sendemail.includestatus.aspx.  When this property is set to true, in the Email that we receive through SendEMail Acitivity will include two links.


1) View Workflow Summary


2) Go to My Tasks


Each of these links takes us to the appropriate page based on the generated URL. The link for View Workflow Summary is constructed correctly, but for Go to My Tasks is not correct.


For e.g


The Workflow Summary URL is correctly setup, pointing to http://myServer.com/Home/_layouts/WrkStat.aspx?List=62d46228-4188-49e5-90f2-31245864b03b&WorkflowInstanceID=234b7864-c37d-42d0-b2bb-964d15cb67a2


For Go to my tasks URL is incorrect setup, pointing to http://myServer.com/SiteA/SiteB/SiteA/SiteB/Lists/Tasks/AllItems.aspx.  The problem being the "SiteA/SiteB” being twice in this case. The link may vary depending on Site Collection level, Site level or Managed property defined.


The Interface type for the send Email action was set to Microsoft.SharePoint.Workflow.ISharePointService. In the SharePoint dll's SPWinOEWSSService class implements this interface.  The Send Email method of this class (SendEmail(Guid workflowId, bool includeStatus, StringDictionary headers, string body)) contains an error where it will incorrectly set the URL.


public void string str4 = parentWeb.Url + currentWorkflow.TaskList.DefaultViewUrl;


parentWeb.Url Equals http://myServer.com/SiteA/SiteB


currentWorkflow.TaskList.DefaultViewUrl Equals /SiteA/SiteB /Lists/AllItems.aspx


In order to fix this issue, we can write a custom activity similar to SendEmail activity and change the URL generated for “Go to My Tasks”


1.  In the Main Workflow code file, have these properties declared.



public Guid workflowId = default(System.Guid);
public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();

2. Code snippet in OnWorkflowActivated Event



Activity1.ItemId = workflowProperties.ItemId;
Activity1.LibId = workflowProperties.ListId;
Activity1.WebId = workflowProperties.WebId;
Activity1.SiteId = workflowProperties.SiteId;
Activity1.WorkflowId = workflowProperties.WorkflowId;

3. Custom Activity code file, variable declarations



public static int ItemId;
public static Guid LibId;
public static Guid WebId;
public static Guid SiteId;
public static Guid WorkflowId;

4. Dependency Property declarations



#region Dependency_Properties
        //BCC
 
        public static DependencyProperty BCCProperty = DependencyProperty.Register("BCC", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Misc")]
        public String BCC
        {
            get
            {
                return ((System.String)(base.GetValue(SendEmailActivity.Activity1.BCCProperty)));
            }
            set
            {
                base.SetValue(SendEmailActivity.Activity1.BCCProperty, value);
            }
        }
 
        //Body
 
        public static DependencyProperty BodyProperty = DependencyProperty.Register("Body", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Misc")]
        public String Body
        {
            get
            {
                return ((System.String)(base.GetValue(SendEmailActivity.Activity1.BodyProperty)));
            }
            set
            {
                base.SetValue(SendEmailActivity.Activity1.BodyProperty, value);
            }
        }
 
        //CC
 
        public static DependencyProperty CCProperty = DependencyProperty.Register("CC", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Misc")]
        public String CC
        {
            get
            {
                return ((System.String)(base.GetValue(SendEmailActivity.Activity1.CCProperty)));
            }
            set
            {
                base.SetValue(SendEmailActivity.Activity1.CCProperty, value);
            }
        }
 
        //From
        public static DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Misc")]
        public String From
        {
            get
            {
                return ((System.String)(base.GetValue(SendEmailActivity.Activity1.FromProperty)));
            }
            set
            {
                base.SetValue(SendEmailActivity.Activity1.FromProperty, value);
            }
        }
 
        //Header
        public static DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Misc")]
        public String Header
        {
            get
            {
                return ((System.String)(base.GetValue(SendEmailActivity.Activity1.HeaderProperty)));
            }
            set
            {
                base.SetValue(SendEmailActivity.Activity1.HeaderProperty, value);
            }
        }
 
        //IncludeStatus
        public static DependencyProperty IncludeStatusProperty = DependencyProperty.Register("IncludeStatus", typeof(System.Boolean), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Misc")]
        public Boolean IncludeStatus
        {
            get
            {
                return ((System.Boolean)(base.GetValue(SendEmailActivity.Activity1.IncludeStatusProperty)));
            }
            set
            {
                base.SetValue(SendEmailActivity.Activity1.IncludeStatusProperty, value);
            }
        }
 
        //Subject
        public static DependencyProperty SubjectProperty = DependencyProperty.Register("Subject", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Misc")]
        public String Subject
        {
            get
            {
                return ((System.String)(base.GetValue(SendEmailActivity.Activity1.SubjectProperty)));
            }
            set
            {
                base.SetValue(SendEmailActivity.Activity1.SubjectProperty, value);
            }
        }
 
        //To
        public static DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Misc")]
        public String To
        {
            get
            {
                return ((System.String)(base.GetValue(SendEmailActivity.Activity1.ToProperty)));
            }
            set
            {
                base.SetValue(SendEmailActivity.Activity1.ToProperty, value);
            }
        }
        //MethodInvoking
        public static DependencyProperty MethodInvokingEvent = DependencyProperty.Register("MethodInvoking", typeof(System.EventHandler), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Handlers")]
        public event EventHandler MethodInvoking
        {
            add
            {
                base.AddHandler(MethodInvokingEvent, value);
            }
            remove
            {
                base.RemoveHandler(MethodInvokingEvent, value);
            }
        }
 
        //InterfaceType
        public static DependencyProperty InterfaceTypeProperty = DependencyProperty.Register("InterfaceType", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Activity")]
        public String InterfaceType
        {
            get
            {
               return "Microsoft.SharePoint.Workflow.ISharePointService";
            }
            
        }
 
        //MethodName
        public static DependencyProperty MethodNameProperty = DependencyProperty.Register("MethodName", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Activity")]
        public String MethodName
        {
            get
            {
               return "SendEmail";
            }
 
        }
 
        //CorrelationToken
        public static DependencyProperty CorrelationTokenProperty = DependencyProperty.Register("CorrelationToken", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Activity")]
        
        public String CorrelationToken
        {
            get
            {
                return ((System.String)(base.GetValue(SendEmailActivity.Activity1.CorrelationTokenProperty)));
            }
            set
            {
                base.SetValue(SendEmailActivity.Activity1.CorrelationTokenProperty, value);
            }
 
        }
 
        //OwnerActivityName
        public static DependencyProperty OwnerActivityNameProperty = DependencyProperty.Register("OwnerActivityName", typeof(System.String), typeof(SendEmailActivity.Activity1));
 
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [BrowsableAttribute(true)]
        [CategoryAttribute("Activity")]
        public String OwnerActivityName
        {
            get
            {
                return ((System.String)(base.GetValue(SendEmailActivity.Activity1.OwnerActivityNameProperty)));
            }
            set
            {
                base.SetValue(SendEmailActivity.Activity1.OwnerActivityNameProperty, value);
            }
 
        }
 
 
        #endregion

5. ExecudeCode method of code activity in custom activity.



SendEmail sE = new SendEmail();
sE.From = From; 
sE.To = To;
sE.Subject = Subject ;
sE.Body = Body; 
CorrelationToken ct = new CorrelationToken(CorrelationToken);
ct.OwnerActivityName = OwnerActivityName;
sE.CorrelationToken = ct;
sE.IncludeStatus = IncludeStatus;
 
 
SPSite site = new SPSite(SiteId);
SPWeb web = site.OpenWeb(WebId);
SPList list = web.Lists[LibId];
SPListItem item = list.GetItemById(ItemId); 
SPWorkflow currentWorkflow = item.Workflows[WorkflowId];
StringDictionary headers = new StringDictionary();
SPWeb parentWeb = currentWorkflow.ParentList.ParentWeb;
string str = SPResource.GetString("DirectionDirValue", new object[0]);
string str2 = headers["subject"];
string str3 = parentWeb.Url + "/" + currentWorkflow.ParentAssociation.StatusUrl + "?List=" + currentWorkflow.ParentList.ID.ToString() + "&WorkflowInstanceID=" + currentWorkflow.InstanceId.ToString();
//string str4 = parentWeb.Url + currentWorkflow.TaskList.DefaultViewUrl;
int sIndex = currentWorkflow.TaskList.DefaultViewUrl.IndexOf("/Lists"); // Depending on the URL, the logic can be changed
string str4 = parentWeb.Url + currentWorkflow.TaskList.DefaultViewUrl.Substring(sIndex);
string body = sE.Body;
body = string.Format(CultureInfo.InvariantCulture, SPResource.GetString("WorkflowChannelEmailHeader", new object[0]), new object[] { str, str2, str3, str4, body });
SPUtility.SendEmail(web, true, false, sE.To, sE.Subject, body);

That’s all we have to do!  Use the custom activity in the workflow and set its properties.  By setting IncludeStatus property to true, and then by running the workflow, we will get a wonderful email with correct URL generated for “Go to My Tasks” link!!


Comments (3)

  1. steclark says:

    Wonder why the boys in Redmond have not fixed this bug yet….

  2. petval says:

    hmm, it 2013 and this still hasn't been fixed yet 🙁

  3. workflow says:

    I am missing SendEmailActivity.dll in my solution . I didn’t find it.

Skip to main content