See how Microsoft Consulting Services can help you
Contact Microsoft Services
Contact The SharePoint Guys
Apply for a job at Microsoft Consulting Services
MCS Solution Dev
The Deployment Guys
MSDN UK
MSDN UK Newsletter
MSDN UK Team Blog
TechNet UK
TechNet UK Newsletter
TechNet UK Blog
Some time ago now, I published a post entitled Quick Tip: Using the SharePoint ‘Person or Group’ field in code which covered details of how to use the ‘Person or Group’ field type in your custom applications.
As I eluded to at the end of that post, one of the most common uses of the ‘Person or Group’ field in custom applications is when you are using the InfoPath Contact Selector control to select people inside an InfoPath form and want to store those values in a ‘Person or Group’ field inside SharePoint. The Contact Selector control is a very powerful control and there is lots of good information about it in these posts:
My own article: Top Tips for InfoPath form development with SharePoint: Part 1 (look for tip 4)
The InfoPath Team Blog: Using the Contact Selector Control
MSDN: The Contact Selector Control
As wonderful as the Contact Selector control is, it leaves a lot to the imagination in terms of storing its values in SharePoint and that is what this post is all about!
The scenario here is that we have a browser–based form (lets say a holiday request form) that gets saved to a SharePoint Form Library when it is submitted. Part of that form is the manager that needs to approve the request which is captured as a Contact Selector.
So the questions is “how do you save your contact selector value to SharePoint?”
The first place I look when trying to do this was to try to promote one of the three values that the Contact Selector generates to a SharePoint ‘Person or Group’ field via InfoPath’s standard property promotion.
The short answer is this did not work. The main reason is that the Contact Selector is not a single field, it is actually 3 different fields (DisplayName, AccountId and AccountType) that are arranged in a very specific XML structure.
You could just bind one of the three fields to SharePoint but the column will be created as a standard ‘text’ type. This is because the three properties contained within the Contact Selector are all text fields in InfoPath. So this will work but it will not be stored as a ‘Person or Group’ field in SharePoint. This is great if you just need the login name, but what we really want is the value to be stored as a ‘Person or group’ field.
Regrettably, the only way to do this is to introduce custom code to your InfoPath form. However, the good news is that the code is fairly simple.
The code sample below deals with multiple values. If you only have a single person in your contact selector it would be much simpler, however this is a more robust solution.
The full code sample is below but these are the main steps:
The code is as follows:
using Microsoft.SharePoint; using Microsoft.Office.Workflow.Utility;
public void FormEvents_Submit(object sender, SubmitEventArgs e) { //actually submit the form e.CancelableArgs.Cancel = false;
//get a navigator bound to the gpContactSelector XPathNavigator xn = this.MainDataSource.CreateNavigator(); XPathNavigator xnManager = xn.SelectSingleNode("/my:myFields/my:Manager/my:gpContactSelector", this.NamespaceManager); //this is the path to the gpContactSelector for your Contact Selector control
//get a semi-colon delimited array of aliases stored inside the contact selector string aliases = ""; using (SPSite site = new SPSite(sSiteURL)) { using (SPWeb web = site.RootWeb) { //add the login name for each person to the string Contact[] contacts = Contact.ToContacts(xnManager.InnerXml, web); if (contacts != null && contacts.Length > 0) { foreach (Contact contact in contacts) { if (contact != null) { aliases += contact.LoginName + ";"; } } } //trim the final ; if (aliases.EndsWith(";")) { aliases = aliases.Substring(0, aliases.Length - 1); } } }
//get the list item that was added by the form. This will depend on the logic of the form, but this simple example goes on the title qGetItem.Query = "<Where><Contains><FieldRef Name='Title'/><Value Type='Text'>" + "some value that represents the title" + "</Value></Contains></Where>"; //replace 'some value that represents the title' with the title of your form SPListItemCollection listitems = web.Lists["FormsLibaryDisplayName"].GetItems(qGetItem); //replace 'FormsLibaryDisplayName' with the name of your form library SPListItem li = listitems[0];
//construction a person field string string personFieldString = ""; string[] aliases_a = aliases.Split(';'); foreach (string alias in aliases_a) { //get an SPUser from the alias SPUser user = web.EnsureUser(alias); //construct the person field sring from the ID and Login name. The ;# separator is the right format for a Sharepoint person or group field personFieldString += user.ID.ToString() + ";#" + user.LoginName.ToString() + ";#"; }
//update the list item li["PersonFieldName"] = personFieldString; //replace 'PersonFieldName' with the name of your Person or Group field in SharePoint li.Update(); }
That is the end of the article, I hope you found it useful.
This article was published by
Martin Kearn Senior Consultant Microsoft Consulting Services UK Martin.Kearn@Microsoft.com
Click here for my bio page