When you first explore the WorklistItem.Delegate() method you might be put off by the fact that it requires a Destinations or Destination object in order to do it's work. Well never fear, here are some methods you can leverage to quickly get this feature integrated into your client event forms:
You'll need a few references and using statements for this code to work
using SourceCode.Hosting.Server.Interfaces;
using SourceCode.Security.UserRoleManager.Client;
using SourceCode.Workflow.Client;
This is an excerpt from my Page_Load() method within my switch statement that is based on page state (look for a future post that discusses creating a page state object and a method to match it) This code could be included in the method executed by your Delegate button or in another aspx form or ... wherever you want it to be. Note that I'm declaring a few private variables before the page_load method for use throughout my methods:
Declarations before PageLoad
SourceCode.Workflow.Client.Connection m_oConn = null;
//bp server from the web.config
private string m_strBPServer = System.Configuration.ConfigurationManager.AppSettings["WorkflowServer"];
Open the connection at the beginning of PageLoad
// open the connection
m_oConn.Open(m_strBPServer);
After deriving the state and getting into my switch statement
case constState.WorklistItemDelegate:
//utilize the resolvetext.. method to split the provided string and resolve to a sourcecode destinations object //Methods below in this text
Destinations oDestinations = ResolveTextToDestination(txtDelegate.Text);
//declare a second destinations object to contain the destinations with the action permissions added
Destinations oDestinationsWithActions = new Destinations();
if (oDestinations.Count != 0)
{
try
{
oWli = m_oConn.OpenWorklistItem(GetSerialNumber(), "ASP", false);
//provide a readout of each destination and resolved type that is being delegated to
lblStatus.Text = "The following have been added to the worklist item's delegation:<Br>";
//while providing the readout, assign permission to all available actions, augment this method to allow for ui that let's the user choose which actions to delegate
foreach (Destination oDestination in oDestinations)
{
lblStatus.Text = lblStatus.Text + "<font color=red>" + oDestination.DestinationType.ToString() + ": " + oDestination.Name + "</font><Br>";
oDestinationsWithActions.Add(AssignPermissionToAllActions(oDestination, oWli));
}
//if the worklist item is open, release it so it will show in the default view of delegate worklists
if (oWli.Status == WorklistStatus.Open) oWli.Release();
//apply the delegation
oWli.Delegate(oDestinationsWithActions);
//provide the next step for the user
lblStatus.Text = lblStatus.Text + "<Br> To reopen the worklist item <i>(which will remove the item from others' worklists)</i> ";
lblStatus.Text = lblStatus.Text + "<a href=" + Request.FilePath.ToString() + "?SN=" + hdnSerialNum.Value + ">Click Here</a>";
//cleanup
Session["m_strProcessName"] = "";
hdnSerialNum.Value = "";
}
catch (Exception eOpenWliException)
{
lblWhatAmIDoing.Text = "Unable to Delegate";
lblStatus.Text = " The worklist could not be delegated<br>" + eOpenWliException.Message.ToString() + "<br>";//;
lblStatus.Text = lblStatus.Text + "<a href=" + Request.AppRelativeCurrentExecutionFilePath.ToString() + "?SN=" + hdnSerialNum.Value + ">Return to Worklist Item</a>";
}
finally
{
m_oConn.Close();
}
}
else
{
lblStatus.Text = lblStatus.Text + "Unable to delegate to users: '" + txtDelegate.Text + "' did not resolve any useable destinations<br>";
lblStatus.Text = lblStatus.Text + "<Br> To reopen the worklist item ";
lblStatus.Text = lblStatus.Text + "<a href=" + Request.FilePath.ToString() + "?SN=" + hdnSerialNum.Value + ">Click Here</a>";
}
break;
These methods use a text string passed from the page_load() area, they parse for comma + space and test to see if each entry is a role, ad group or ad user. There are definitely other ways of accomplishing this more neatly from the UI (drop down lists etc), but this example displays maximum flexibility for handling user input so anything else should be simpler to implement.
private Destination AssignPermissionToAllActions(Destination oDestination, WorklistItem oWli)
{
foreach (Action oAction in oWli.Actions)
{
oDestination.AllowedActions.Add(oAction.Name);
}
return oDestination;
}
private Destinations ResolveTextToDestination(string strDelegateText)
{
//split the incoming string into a string array of possible destinations
string[] strDestinations = Regex.Split(strDelegateText, ", ");
//declare a destinationS object to pass back to the calling method
Destinations oDestinations = new Destinations();
//for loop over the incoming destinations string array
for (int i = 0; i < strDestinations.Length; i++)
{
//clear the temp destination object
Destination oDestination = new Destination();
//derive the type of destination and add a destination object to oDestinationS for each one
oDestination = TestDestinationIsARole(strDestinations[i]);
if (oDestination.Name != string.Empty)
{
oDestinations.Add(oDestination);
}
else
{
oDestination = TestDestinationIsAGroup(strDestinations[i]);
if (oDestination.Name != string.Empty)
{
oDestinations.Add(oDestination);
}
else
{
oDestination = TestDestinationIsAUser(strDestinations[i]);
if (oDestination.Name != string.Empty)
{
oDestinations.Add(oDestination);
}
}
}
}
return oDestinations;
}
private Destination TestDestinationIsARole(string strDestinationName)
{//check that role exists by trying to resolve it's queue to an object
UserRoleManagerServer umClient = new UserRoleManagerServer();
SCConnectionStringBuilder cb = new SCConnectionStringBuilder();
Destination oDestination = new Destination();
//Build a SC Connection String
cb.Host = m_strBPServer;
cb.Port = Convert.ToUInt32(m_strBPServerPort);
cb.Integrated = true;
cb.IsPrimaryLogin = true;
//Open the connection to K2
umClient.CreateConnection();
umClient.Connection.Open(cb.ToString());
//Obtain a collection of users for this role
try
{
// IUserCollection roleUsers = ;
if (umClient.ResolveQueue(strDestinationName) != null)
{ //Close the Connection
umClient.Connection.Close();
oDestination.DestinationType = DestinationType.Role;
oDestination.Name = strDestinationName;
return oDestination;
}
else
{
//Close the Connection
umClient.Connection.Close();
return oDestination;
}
}
catch
{
return oDestination;
}
}
private Destination TestDestinationIsAGroup(string strDestinationName)
{
if (strDestinationName.IndexOf(@"\") == -1) strDestinationName = m_strDefaultADDomain + @"\" + strDestinationName;
if (strDestinationName.IndexOf(":") == -1) strDestinationName = m_strDefaultLabel + ":" + strDestinationName;
UserRoleManagerServer umClient = new UserRoleManagerServer();
SCConnectionStringBuilder cb = new SCConnectionStringBuilder();
Destination oDestination = new Destination();
//Build a SC Connection String
cb.Host = m_strBPServer;
cb.Port = Convert.ToUInt32(m_strBPServerPort);
cb.Integrated = true;
cb.IsPrimaryLogin = true;
//Open the connection to K2
umClient.CreateConnection();
umClient.Connection.Open(cb.ToString());
//Obtain a collection of users for this role
try
{
if (umClient.GetGroup(strDestinationName, m_strDefaultLabel, "") != null)
{ //Close the Connection
umClient.Connection.Close();
oDestination.DestinationType = DestinationType.Group;
oDestination.Name = strDestinationName;
return oDestination;
}
else
{
//Close the Connection
umClient.Connection.Close();
return oDestination;
}
}
catch
{
return oDestination;
}
}
private Destination TestDestinationIsAUser(string strDestinationName)
{
if (strDestinationName.IndexOf(@"\") == -1) strDestinationName = m_strDefaultADDomain + @"\" + strDestinationName;
if (strDestinationName.IndexOf(":") == -1) strDestinationName = m_strDefaultLabel + ":" + strDestinationName;
Destination oDestination = new Destination();
UserRoleManagerServer umClient = new UserRoleManagerServer();
SCConnectionStringBuilder cb = new SCConnectionStringBuilder();
//Build a SC Connection String
cb.Host = m_strBPServer;
cb.Port = Convert.ToUInt32(m_strBPServerPort);
cb.Integrated = true;
cb.IsPrimaryLogin = true;
//Open the connection to K2
umClient.CreateConnection();
umClient.Connection.Open(cb.ToString());
//Obtain a collection of users for this role
try
{
if (umClient.GetUser(strDestinationName, m_strDefaultLabel, "") != null)
{ //Close the Connection
umClient.Connection.Close();
oDestination.DestinationType = DestinationType.User;
oDestination.Name = strDestinationName;
return oDestination;
}
else
{
//Close the Connection
umClient.Connection.Close();
return oDestination;
}
}
catch
{
return oDestination;
}
}