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));
public String Body
return ((System.String)(base.GetValue(SendEmailActivity.Activity1.BodyProperty)));
base.SetValue(SendEmailActivity.Activity1.BodyProperty, value);
//CC
public static DependencyProperty CCProperty = DependencyProperty.Register("CC", typeof(System.String), typeof(SendEmailActivity.Activity1));
public String CC
return ((System.String)(base.GetValue(SendEmailActivity.Activity1.CCProperty)));
base.SetValue(SendEmailActivity.Activity1.CCProperty, value);
//From
public static DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(System.String), typeof(SendEmailActivity.Activity1));
public String From
return ((System.String)(base.GetValue(SendEmailActivity.Activity1.FromProperty)));
base.SetValue(SendEmailActivity.Activity1.FromProperty, value);
//Header
public static DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(System.String), typeof(SendEmailActivity.Activity1));
public String Header
return ((System.String)(base.GetValue(SendEmailActivity.Activity1.HeaderProperty)));
base.SetValue(SendEmailActivity.Activity1.HeaderProperty, value);
//IncludeStatus
public static DependencyProperty IncludeStatusProperty = DependencyProperty.Register("IncludeStatus", typeof(System.Boolean), typeof(SendEmailActivity.Activity1));
public Boolean IncludeStatus
return ((System.Boolean)(base.GetValue(SendEmailActivity.Activity1.IncludeStatusProperty)));
base.SetValue(SendEmailActivity.Activity1.IncludeStatusProperty, value);
//Subject
public static DependencyProperty SubjectProperty = DependencyProperty.Register("Subject", typeof(System.String), typeof(SendEmailActivity.Activity1));
public String Subject
return ((System.String)(base.GetValue(SendEmailActivity.Activity1.SubjectProperty)));
base.SetValue(SendEmailActivity.Activity1.SubjectProperty, value);
//To
public static DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(System.String), typeof(SendEmailActivity.Activity1));
public String To
return ((System.String)(base.GetValue(SendEmailActivity.Activity1.ToProperty)));
base.SetValue(SendEmailActivity.Activity1.ToProperty, value);
//MethodInvoking
public static DependencyProperty MethodInvokingEvent = DependencyProperty.Register("MethodInvoking", typeof(System.EventHandler), typeof(SendEmailActivity.Activity1));
[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));
[CategoryAttribute("Activity")]
public String InterfaceType
return "Microsoft.SharePoint.Workflow.ISharePointService";
//MethodName
public static DependencyProperty MethodNameProperty = DependencyProperty.Register("MethodName", typeof(System.String), typeof(SendEmailActivity.Activity1));
public String MethodName
return "SendEmail";
//CorrelationToken
public static DependencyProperty CorrelationTokenProperty = DependencyProperty.Register("CorrelationToken", typeof(System.String), typeof(SendEmailActivity.Activity1));
public String CorrelationToken
return ((System.String)(base.GetValue(SendEmailActivity.Activity1.CorrelationTokenProperty)));
base.SetValue(SendEmailActivity.Activity1.CorrelationTokenProperty, value);
//OwnerActivityName
public static DependencyProperty OwnerActivityNameProperty = DependencyProperty.Register("OwnerActivityName", typeof(System.String), typeof(SendEmailActivity.Activity1));
public String OwnerActivityName
return ((System.String)(base.GetValue(SendEmailActivity.Activity1.OwnerActivityNameProperty)));
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!!
I am missing SendEmailActivity.dll in my solution . I didn't find it.