Issue with Multi Field/Group values and SPWorkflowTaskProperties.ExtendedProperties
I encountered an issue when assigning a multi-user data to a workflow task field from within the workfflow.
There may be various reasons anyone wants to create a User/Group field with multiple values and set it within in the workflow as below,
SPWorkflowTaskProperties.ExtendedProperties["CustomAssignToUsers"] = "domain\user1;domain\user2";
SharePoint checks the property collection and strips off the multiple user data from the property for type SPFieldUser.
As a workaround, we can create a custom field which inherits from the SPFieldUser, this new field type bypass the control type checks within SharePoint.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Xml;
namespace MyCurrentUserFieldNS
{
public class MyCurrentUserField : SPFieldUser
{
public MyCurrentUserField(SPFieldCollection fields, string fieldName)
: base(fields, fieldName)
{
this.Presence = true;
}
public override bool AllowMultipleValues
{
get
{
return true;
}
set
{
base.AllowMultipleValues = true;
}
}
//There is an issue with the SPFieldUser,setting the 'AllowMultipleValues' resets the
//Control 'Type'. As a workaround, I override this function and update the field schema
public override void OnAdded(SPAddFieldOptions op)
{
base.OnAdded(op);
XmlDocument doc = new XmlDocument();
doc.LoadXml(this.SchemaXml);
XmlNode element = doc.FirstChild;
XmlAttribute attr = doc.CreateAttribute("Mult");
attr.Value = "TRUE";
element.Attributes.Append(attr);
this.SchemaXml = doc.OuterXml;
base.Update();
}
public MyCurrentUserField(SPFieldCollection fields, string typeName, string displayName)
: base(fields, typeName, displayName)
{
this.Presence = true;
}
public override Type FieldValueType
{
get
{
return typeof(SPFieldUserValueCollection);
}
}
public override BaseFieldControl FieldRenderingControl
{
get
{
BaseFieldControl fldControl = new UserField();
fldControl.FieldName = InternalName;
return fldControl;
}
}
}
}
<FieldTypes>
<FieldType>
<Field Name="TypeName">MyCurrentUserField</Field>
<Field Name="ParentType">LookupMulti</Field>
<Field Name="TypeDisplayName">My Current User</Field>
<Field Name="TypeShortDescription">My Current User</Field>
<Field Name="Mult">TRUE</Field>
<Field Name="UserCreatable">TRUE</Field>
<Field Name="ShowInListCreate">TRUE</Field>
<Field Name="ShowInSurveyCreate">TRUE</Field>
<Field Name="ShowInDocumentLibraryCreate">TRUE</Field>
<Field Name="ShowInColumnTemplateCreate">TRUE</Field>
<Field Name="FieldTypeClass">MyCurrentUserFieldNS.MyCurrentUserField, MyCurrentUserField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=79330dc34f5433ec</Field>
<Field Name="FieldEditorUserControl">/_controltemplates/UserFieldEditor.ascx</Field>
</FieldTypes>
Save the second markup as ‘FLDTYPES_MyCurrentUserField.xml’ and paste it under ..\12\TEMPLATE\XML folder
Build an assembly using the code snippet provided below, strong name it.
Ensure that you change the ‘FLDTYPES_MyCurrentUserField.xml’ according to the binary version and the publictokenkey.
Other Resources
Custom Field Types
https://msdn.microsoft.com/en-us/library/ms446361.aspx
Create a custom field type and a field Control
https://msdn.microsoft.com/en-us/library/bb417414.aspx
Enjoy!