Saturday, July 18, 2015

Emails in a K2 workflow stopped working after deploying new workflow version.

The workflow fails while trying to send a notification with the error "SourceCode.Workflow.Common.EWS: The e-mail address does not have ‘send on behalf of’ permissions on Exchange".


  1. Check if SMTP server, Exchange server connection strings are correct in “ConnectionStringEditor.exe”
  2. Open Connection String editor from "C:\Program Files (x86)\K2 blackpearl\Host Server\Bin" as Administrator.





  1. Check if Email "From Address" field value is a valid email in Environment Fields/String Table and same as the email displayed in the connection String editor.
  2. Restart IIS, MSMQ and K2 services.

Get Emails for Multiple Destination Users in K2 Workflow

In Workflows, sometime we may need to get emails for dynamic destination users (one or more destination users separated by semi-colon ’;’).
To achieve this, we need to do as follows:

  1. Add two Process Data Fields, one for storing User IDs and another for getting User emails.

  1. MultiUserIDs – Process field to store semi-colon(;) separated list of User IDs
Ex: k2:denallix\administrator;k2:denallix\bob.
Note: you can also pass  data without K2 label,
Ex: denallix\administrator;denallix\bob


  1. MultiUserEmails – Process field to fetch and store semi-colon(;) separated list of User Email Ids for the input User IDs.

  1. Add a default Activity. Configure the destination rules as follows:

  1. Run the Destination Wizard in “Advanced Mode”


  1. Select “All at Once”


  1. Select “Create a slot for each destination” and “Resolve all roles and groups to users”


  1. In the Destination Sets, Add New Destination with Split function as follows:

  1. Click on “Finish” button

  1. Add the event, “Default Server Event(Code)” to the above activity.

  1. Go to the code event by,

  1. Add the following Code for the code event. This code will loop through the destination users and get emails for the multiple destination users and concatenate them with semi-colon(;).

  1. That’s it. After that, you can add an email event with “MultiDestEmails” as “To field’ to send emails to all destination Users.

  1. Once you run this, you will get the Output as follows:

Friday, April 10, 2015

Exception Logging in K2

public class K2ExceptionHandler
    {
            System.Net.Mail.MailMessage expMail = null;
            System.Net.Mail.SmtpClient smtpClient = null;
            System.Net.Mail.MailAddress mailAddressFrom = null;
            Exception ex = null;
            object exContext = null;             
            string emailBody = string.Empty;
            bool bFlag = true;

            public void SendExceptionEmail(SourceCode.KO.ExceptionContext K2)
            {
            try
            {
                smtpClient = new System.Net.Mail.SmtpClient();

                expMail = new System.Net.Mail.MailMessage();

                //Mail To Address
                string mailTO = System.Configuration.ConfigurationManager.AppSettings["ExceptionEmailTo"]; // Get it from K2HostServer.exe.config file, located at "C:\Program Files (x86)\K2 blackpearl\Host Server\Bin"
                expMail.To.Add(mailTO);

                //Email From Address - Get it from String tabble
                string fromAddress = K2.StringTable["From Address"];
                mailAddressFrom = new System.Net.Mail.MailAddress(fromAddress);
                expMail.From = mailAddressFrom;

                //Email Subject
                expMail.Subject = "K2 Error: ProcessID " + K2.ProcessInstance.ID.ToString() + " for the Process, '" + K2.ProcessInstance.Process.FullName + "' is in error state";

                //Send HTML Email
                expMail.IsBodyHtml = true;
                expMail.Priority = System.Net.Mail.MailPriority.High;

                // Basic Message
                emailBody += "";
                emailBody += "";
                emailBody += "";
                emailBody += "";
                emailBody += "K2 Notification";
                emailBody += "
";
                emailBody += "";

                emailBody += ""
;
                emailBody += "
Dear Administrator,
";
                emailBody += "

";

                emailBody += "
"
+ " Error occurred in the K2 workflow, '" + K2.ProcessInstance.Process.FullName + "
' for the Process Intstance ID, '" + K2.ProcessInstance.ID.ToString() + "'. Below is a detailed extraction of the error and the process instance.";
                emailBody += "

";

                #region Process Instance Details

                emailBody += "
Process Intstance Details
";
                              
                emailBody += " " ;
                emailBody += "
"
;
                emailBody += ""
;

                emailBody += " " ;
                emailBody += "
ID:
";
                emailBody += "
"
+ K2.ProcessInstance.ID.ToString() + "
";
                emailBody += "
";

                emailBody += " " ;
                emailBody += "
Process Name:
";
                emailBody += "
"
+ K2.ProcessInstance.Process.FullName + "
";
                emailBody += "
";
               
                emailBody += " " ;
                emailBody += "
Folio:
";
                emailBody += "
"
+ K2.ProcessInstance.Folio + "
";
                emailBody += "
";
              
                emailBody += " " ;
                emailBody += "
Originator:
";
                emailBody += "
"
+ K2.ProcessInstance.Originator.DisplayName + "
";
                emailBody += "
";
                emailBody += " " ;
                emailBody += "
Start Date:
";
                emailBody += "
"
+ K2.ProcessInstance.StartDate.ToString() + "
";
                emailBody += "
";

                emailBody += "
";
                emailBody += "
";
                emailBody += "
";
                emailBody += "

";

                #endregion

                #region Process Data Fields
                emailBody += "
Data Field Values
";
                emailBody += " " ;
                emailBody += "
"
;
                emailBody += ""
;



                foreach (SourceCode.KO.DataField _dataField in K2.ProcessInstance.DataFields)
                {
                    emailBody += " " ;
                    emailBody += "
"
+ _dataField.Name + " [" + _dataField.FieldType.ToString() + "]
";
                    emailBody += "
"
+ _dataField.Value.ToString() + "
";
                    emailBody += "
";


                emailBody += "
";
                emailBody += "
";
                emailBody += "
";
                emailBody += "

";
                #endregion

                #region Failure Details
                emailBody += "
Failure Details
";
                emailBody += " " ;
                emailBody += "
"
;
                emailBody += ""
;

                //Check where the error happened
                switch (K2.ContextType)
                {
                    case SourceCode.KO.ContextType.ClientEvent:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.ClientEventContext)exContext).ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.ClientEventContext)exContext).Event.Name + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.DestinationRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.DestinationRuleContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Destinations:
";
                            emailBody += "
"
;
                            foreach (SourceCode.KO.Destination _dest in ((SourceCode.KO.DestinationRuleContext)exContext).Destinations)
                            {
                                emailBody += " " + _dest.Name + " [" + _dest.Type.ToString() + "];";
                            }
                            emailBody += "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Slot Data:
";
                            emailBody += "
"
;
                            foreach (string _slotdata in ((SourceCode.KO.DestinationRuleContext)exContext).SlotInstanceData)
                            {
                                emailBody += " " + _slotdata + ";";
                            }
                            emailBody += "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Dynamic Queues:
";
                            emailBody += "
"
+ ((SourceCode.KO.DestinationRuleContext)exContext).DynamicQueues.ToString() + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Resolve queues to users:
";
                            emailBody += "
"
+ ((SourceCode.KO.DestinationRuleContext)exContext).ResolveQueuesToUsers.ToString() + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Single instance:
";
                            emailBody += "
"
+ ((SourceCode.KO.DestinationRuleContext)exContext).SingleInstance.ToString() + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Number of slots:
";
                            emailBody += "
"
+ ((SourceCode.KO.DestinationRuleContext)exContext).Slots.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.EscalationAction:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EscalationActionContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Redirect:
";
                            emailBody += "
"
+ ((SourceCode.KO.EscalationActionContext)exContext).Redirect.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.EscalationRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EscalationRuleContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.EventEscalationAction:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventEscalationActionContext)exContext).EventInstance.ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventEscalationActionContext)exContext).EventInstance.Event.Name + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.EventEscalationRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventEscalationRuleContext)exContext).EventInstance.ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventEscalationRuleContext)exContext).EventInstance.Event.Name + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.EventSucceedingRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventSucceedingRuleContext)exContext).EventInstance.ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventSucceedingRuleContext)exContext).EventInstance.Event.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Succeeding rule:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventSucceedingRuleContext)exContext).SucceedingRule.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.IPCEvent:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.IPCEventContext)exContext).ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.IPCEventContext)exContext).Event.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
IPC process:
";
                            emailBody += "
"
+ ((SourceCode.KO.IPCEventContext)exContext).Process + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
IPC connection string:
";
                            emailBody += "
"
+ ((SourceCode.KO.IPCEventContext)exContext).ConnectionString + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Synchronous:
";
                            emailBody += "
"
+ ((SourceCode.KO.IPCEventContext)exContext).Synchronous + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.LineRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Start activity name:
";
                            emailBody += "
"
+ ((SourceCode.KO.LineRuleContext)exContext).LineInstance.StartActivityInstance.Activity.Name + "
";
                            emailBody += "
";

                            //The folllowing throws error as it does not have finish activity details
                            //_emailBody += " ";
                            //_emailBody += "
Finish activity:
";
                            //_emailBody += "
" + ((SourceCode.KO.LineRuleContext)_exContext).LineInstance.FinishActivityInstance.Activity.Name + "
";
                            //_emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Line name:
";
                            emailBody += "
"
+ ((SourceCode.KO.LineRuleContext)exContext).LineInstance.Line.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Line rule:
";
                            emailBody += "
"
+ ((SourceCode.KO.LineRuleContext)exContext).LineRule.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.PrecedingRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity name:
";
                            emailBody += "
"
+ ((SourceCode.KO.PrecedingRuleContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Preceeding rule:
";
                            emailBody += "
"
+ ((SourceCode.KO.PrecedingRuleContext)exContext).PrecedingRule.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.ProcessEscalationAction:
                    case SourceCode.KO.ContextType.ProcessEscalationRule:
                    case SourceCode.KO.ContextType.ProcessFinishRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.ProcessStartRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Message:
";
                            emailBody += "
"
+ ((SourceCode.KO.ProcessStartRuleContext)exContext).Message + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Start rule:
";
                            emailBody += "
"
+ ((SourceCode.KO.ProcessStartRuleContext)exContext).Start.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.ServerEvent:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.ServerEventContext)exContext).ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.ServerEventContext)exContext).Event.Name + "
";
                            emailBody += "
";

                            break;
                        }
                    case SourceCode.KO.ContextType.StartRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.StartRuleContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.SucceedingRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.SucceedingRuleContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Succeeding rule:
";
                            emailBody += "
"
+ ((SourceCode.KO.SucceedingRuleContext)exContext).SucceedingRule.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    default:
                        {
                            emailBody += "
colspan=\"2\">No details available
";
                            break;
                        }
                }

                emailBody += "
";
                emailBody += "
";
                emailBody += "
";
                emailBody += "

";
                #endregion

                #region Exception Details
                emailBody += "
Exception Details
";
                emailBody += " " ;
                emailBody += "
"
;
                emailBody += ""
;

                ex = new Exception("NOTHING");
                ex = (Exception)K2.ExceptionObject;
                bFlag = true;
                while (bFlag == true)
                {
                    if (ex.InnerException != null)
                    {
                        ex = ex.InnerException;
                    }
                    else
                    {
                        emailBody += " " ;
                        emailBody += "
Message:
";
                        emailBody += "
"
+ ex.Message + "
";
                        emailBody += "
";

                        emailBody += " " ;
                        emailBody += "
Stack Trace:
";
                        emailBody += "
"
+ ex.StackTrace + "
";
                        emailBody += "
";
                        bFlag = false;
                    }
                }
               
                emailBody += "
";
                emailBody += "
";
                emailBody += "
";
              
                #endregion

                

                #region View Flow link

                string K2ServerName = string.Empty;

                //Workflow Management Server
                string strWorkflowServer = K2.StringTable["Workflow Server"]; //Integrated=True;IsPrimaryLogin=True;Authenticate=True;EncryptedPassword=False;Host=dlx;Port=5252
                string[] workflowServerDetails = strWorkflowServer.Split(';');
                foreach (string strWorkflowServerDetail in workflowServerDetails)
                {
                    if (strWorkflowServerDetail.Contains("Host"))
                    {
                        K2ServerName = strWorkflowServerDetail.Substring(strWorkflowServerDetail.IndexOf('=') + 1);
                    }
                }

                string strViewFlowURL = @"http://###K2Server###:81/ViewFlow/ViewFlow.aspx?ViewTypeName=ProcessView&K2Server=###K2Server###:5252&HostServerName=###K2Server###&HostServerPort=5555&ProcessID=###ProcinstID###";
                strViewFlowURL = strViewFlowURL.Replace("###K2Server###", K2ServerName);
                strViewFlowURL = strViewFlowURL.Replace("###ProcinstID###", K2.ProcessInstance.ID.ToString());

                string strViewFlowLink = "<" + "a href='" + strViewFlowURL + "' target=_blank>Click Here
";
                emailBody += "

";
                emailBody += "
To open the K2 View Flow, "
+ strViewFlowLink + ".
";
                emailBody += "

";
                #endregion


                emailBody += "
Regards,
";
                emailBody += "
K2 Exception Handler
";
                emailBody += "
";
                emailBody += "
";
                emailBody += "
";

                expMail.Body = emailBody;

                #region Send Email

                string smtpMailServer = K2.StringTable["Mail Server"]; //Get mail server from String table

                using (smtpClient as IDisposable)
                {

                    if (smtpMailServer.IndexOf(":") == -1)
                    {
                        smtpClient.Host = smtpMailServer;
                    }
                    else
                    {
                        string[] connection = smtpMailServer.Split(new Char[] { ':' });

                        Int32 I = 0;

                        if (string.IsNullOrEmpty(connection[0]) || string.IsNullOrEmpty(connection[1]))
                        {
                            throw new Exception("Invalid SMTP Server / Port arguments supplied.");
                        }

                        // PORT 2ND PARM ONLY!
                        if (Int32.TryParse(connection[1], out I))
                        {
                            smtpClient.Host = connection[0];
                            smtpClient.Port = Int32.Parse(connection[1]);
                        }
                        else
                        {
                            throw new Exception("Invalid SMTP Server / Port arguments supplied.");
                        }
                    }
                    using (expMail)
                    {
                        smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
                        smtpClient.UseDefaultCredentials = true;
                        smtpClient.Send(expMail);                       
                    }
                }
                #endregion
            }
            catch (Exception expMail)
            {
                //Console.WriteLine("[Process Error Notify] Error sending email: " + exMail.Message); //todo Log error to Sharepoint Logs
            }
            finally
            {
                expMail = null;
                smtpClient = null;
                mailAddressFrom = null;
                throw ((Exception)K2.ExceptionObject);
            }
        }

    }