So we had a requirement where we needed to create and assign a SharePoint task to all site collection administrators upon the creation of a new forms based user. Essentially, once a user registers it assigns a new Task to all administrators asking them to assign that user to a group. Those tasks are exposed on the administrators view of the world (a filtered view on their landing page).
Here’s how it’s done. Firstly, you need to hook the CreatedUser event on the CreateUserWizard control that you used for registering your FBA user. (I appologise in advance for the poor code formatting).
protected void Page_Load(object sender, EventArgs e)
{
CreateUserWizard1.CreatedUser += new EventHandler(CreateUserWizard1_CreatedUser);
}
Secondly, you need to define the CreatedUser event:
void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
// Firstly we elevate our privleges so that we can create and modify tasks.
SPSecurity.RunWithElevatedPrivleges(delegate {
// To get the username and password of the created user, access the wizard via the sender
CreateUserWizard wizard = (CreateUserWizard) sender;
// Now we reference the site – note we need to create a new site object reference so that it uses the elevated context, otherwise we will be executing code as the current user instead of the system user.
using (SPSite site = new SPSite(SPContext.Current.Site.Url)
{
// Now we need to allow safe updates, so we dont get any security validation errors when updating the list item
site.AllowUnsafeUpdates = true;
// Now we grab the web object, once again we use openweb on the current site so we stay in system context, and we do it via the using block to ensure that our objects are disposed after we are finished with them
using(SPWeb web = site.OpenWeb())
{
// Let’s allow safe updates on the web as well
web.AllowSafeUpdates = true;
// Now we have our context web, we can access the task list
SPList tasks = web.Lists["Tasks"];
// Call our custom method to create the new tasks for every site collection admin:
CreateTasksForAllAdmins(tasks, web, wizard.UserName, wizard.Email);
}
}
});
}
// Now we define a method which goes through all of our site collection admins and creates a new task for each of them
void CreateTasksForAllAdmins(SPList list, SPWeb web, string username, string email)
{
// Iterate over all of the site users (this include all of our site collection admins, if they havent logged in previously, you may need to do an ‘ensureuser’ here).
foreach(SPUser user in web.SiteUsers)
{
// check if they are a site admin
if(user.IsSiteAdmin)
{
// Create a new task item
SPListItem myTask = list.Items.Add();
// Now we need to create an SPFieldUserValueCollection which stores a list of users for the ‘AssignedTo’ field. We use this to allocate a user to the task.
SPFieldUserValueCollection fv = new SPFieldValueCollection();
// add the new user into the collection
fv.Add(new SPFieldUserValue(web, user.ID, user.Name));
// Assign the user to the task
myTask["AssignedTo"] = fv; // Note, you can use the enumeration here if you want for corefields
myTask["Title"] = ”Created ” + username;
// usually you would create a link to the /_layouts/people.aspx page here in the description too.
myTask["Description"] = string.format(“created user {0} with email {1}”, username, email);
// Finally update the task which adds it to the list and assigns the user…
myTask.Update();
}
}
}
Done
Now each administrator will get a new task created in the task list when a user registers via FBA to SharePoint. I’ve used a SQL membership backend store, but you can use whatever you want – just utilize the ASP.NET login controls in a custom layout page, or however you want to manage the registration
There’s a few tricky things here that caught me out – one of them was the SPFieldUserValueCollection that you need to assign to the AssignedTo field – SharePoint uses this collection as a lookup, as a means to collect multiple users when assigning them to a task (if you look in the newform for the task, youll see you can add multiple users – all they are, is comma delimited strings being added (with an identifier) to this collection). You then just shove that collection into the AssignedTo field. NOTE: When you assign it to the field and call Update(), it doesnt store a reference to the SPFieldUserValueCollection, it serialises it into a string, and stores a string representation of the collection into the field. So if you come back again, and try cast it back to one of these, it will fail. Instead, call the (web, string) constructior on the SPFieldUserValueCollection and pass it the string representation as the second argument, it will then deserialise it back into one of these collections for you
HTH,
Matt
Did this post help you? If so, feel free to show me some support by clicking here and donating!
[...] Programmatically creating and assigning a SharePoint task [...]
I am using Key property of PickerEntity to pass it from an initiation form.
How do I set parameters of SPFieldUserValueCollection and SPFieldUserValue
objects considering that I do not have a SPUser object?
Thanks in advance
Hi Zarko,
You can easily retrieve the SPUser by using something along the lines of:
Hashtable data = pickerEntity.EntityData;
string loginName = pickerEntity.Key; // login name
string email = data["Email"].ToString(); //email
string displayName = data["DisplayName"]; // display name
// Retrieve the user (if it is a user! it might be a group, look it up in sitegroups first if you are allowing groups, before trying to get it as a user)
SPUser user = null;
user = SPContext.Current.Web.SiteUsers.GetByEmail(email);
You can also get the SPUserID out of the data hashtable instead of te email, and use GetUserById() on the SiteUsers collection.
Hope this helps,
Matthew Cosier
Matthew, thank you for your reply. However, I haven’t solved my problem yet.
I get an error massage “Value does not fall within the expected range”. I am a
beginner in SharePoint programming and need to create a custom workflow.
I need to assign tasks(bound to the same document) to a certain number of users and keep track of their responses. I tried to do it using activities from the toolbox in visual studio but I found that the column “Assigned to” in the task list cannot contain multiple values. Now I am trying to do it manually within the code activity.
Any suggestions?
Thanks in advance
Matthew, I found solution for my problem. Now I need to manually set the Status field in tasks list manually to a desired value.
Any ideas?