Friday, August 28, 2009

Get WorkFlow Task Item from List Item Id

 

        public static SPListItem WorkflowTaskItemBasedOnListItem(SPWeb web, string listName, string workflowTaskListName, int itemId)
        {
            SPListItem workflowItem = null;
            SPList workflowTasks = web.Lists[workflowTaskListName];
            SPList mainList = web.Lists[listName];
            SPListItem listItem = mainList.GetItemById(Convert.ToInt32(itemId));
            SPWorkflowFilter filter = new SPWorkflowFilter();
            filter.InclusiveFilterStates = SPWorkflowState.Running;
            // Get a list of workflow tasks associated with current Item
            SPWorkflowTaskCollection workTaskColl = web.Site.WorkflowManager.GetItemTasks(listItem, filter);
            foreach (SPWorkflowTask task in workTaskColl)
            {
                if (task != null)
                {
                    workflowItem = workflowTasks.GetItemById(task.ID);
                    break;
                }
            }

            return workflowItem;
        }

 

This function returns a workflow item based on Parent List item Id. It reads the List Item and finds the associated workflow which are still running against this list item.

Type 'Microsoft.SharePoint.SPUser' in Assembly 'Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' is not marked as serializable. Type 'Microsoft.SharePoint.SPUser' in Assembly

Make sure you are not storing any object of SPUser type in Session on ViewState. I was getting this error SPUser was persist in ViewState. We changed the logic to store LoginName and everything worked fine

The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again

Recently, I was getting this error when non-admin were trying to alter a workflow task. My code was running under elevated permission using the option first as described in my last post(using SharePoint\System) user

To fix, I need to run the code under elevated permission using second option as described in my last post(RunWithElevatedPrivileges)


    string siteURL = SPContext.Current.Site.Url;
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
        SPSite objSite = new SPSite(siteURL);
        SPWeb web= objSite.OpenWeb();

        web.AllowUnsafeUpdates = true;

        Hashtable taskHash = new Hashtable();
        SPListItem item = null;
        item["Status"] = "Completed";
        SPWorkflowTask.AlterTask(item, taskHash, false);
        web.AllowUnsafeUpdates = false;
    });

Running Code with Elevated Permissions

 

There are 2 ways to run code under elevated permissions. The first one is using the token created from SharePoint\System(internal user) user

public static SPWeb GetElevatedWeb
        {
            get
            {
                var superUser = SPContext.Current.Web.AllUsers[@"SHAREPOINT\SYSTEM"];
                var superToken = superUser.UserToken;
                using (var site = new SPSite(SPContext.Current.Web.Url, superToken))
                {
                    return site.RootWeb;
                }
            }
        }

This function returns a SPWeb object which is created using elevated permissions

The second method is using SPSecurity.RunWithElevatedPrivileges

public static SPWeb GetSPElevatedWeb
        {
            get
            {
                SPWeb web = null;
                string siteURL = SPContext.Current.Site.Url;
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPSite objSite = new SPSite(siteURL);
                    web = objSite.OpenWeb();
                });
                return web;
            }
        }

The SPSite object is created by reading the SPContext object before calling RunWithElevatedPrivileges as the context will change in the code block

Monday, August 03, 2009

Create custom groups in SharePoint

To create custom groups in SharePoint, use the SPWeb SiteGroups collection.

web.SiteGroups.Add(groupName, owner, member, description)

Groups created using code will not automatically appear in left navigation. For them to appear there, the groups need to be associated with web. The code to this is

web.Properties["vti_associategroups"] = web.Properties["vti_associategroups"] + “;” +  web.SiteGroups[groupName].ID.ToString();

web.Properties.Update();

Function to read List Item Id based on task

taskListItemId = id of task item

web = Web object

SPListItem taskItem = taskList.GetItemById(taskListItemId);
Guid workflowInstanceId = new Guid((string)taskItem["WorkflowInstanceID"]);
SPWorkflow workflowInstance = new SPWorkflow(web, workflowInstanceId);
SPList itemList = workflowInstance.ParentList;
SPListItem parentListItemId = itemList.GetItemById(workflowInstance.ItemId);

Other way of getting Elevated Web

SPUser superUser = SPContext.Current.Web.AllUsers[@"SHAREPOINT\SYSTEM"];
string superToken = superUser.UserToken;
using (var site = new SPSite(SPContext.Current.Web.Url, superToken))

      return site.RootWeb; 
}

This function would return a web object running under the super user “SharePoint\System” (inbuilt) account

Retrieve the attachments of List Item

To retrieve the attachment, access the folder object of the item and then read the files

SPFolder folder = Web.Folders["Lists"].SubFolders[listName];

folder = folder.SubFolders["Attachments"].SubFolders[itemNo];
foreach (SPFile file in folder.Files)
{
}

Read AD SPUser in SharePoint

Web object’s AllUsers property returns user which have accessed the site. To validate a user which has never existed on the site use

Web.EnsureUser(strUserLogin);

Add\remove Quick launch link

       Add a quick launch link group

     public static void AddQuickLaunchGroup(SPWeb web, string groupName)
        {
            SPNavigationNodeCollection quickLaunchNodes = web.Navigation.QuickLaunch;
            SPNavigationNode groupMenu = new SPNavigationNode(groupName, "", false);
            quickLaunchNodes.AddAsFirst(groupMenu);
            web.Update();
        }

        Remove quick link group-

        public static void RemoveQuickLaunchGroup(SPWeb web, string groupName)
        {
            SPNavigationNodeCollection quickLaunchNodes = web.Navigation.QuickLaunch;
            foreach (SPNavigationNode node in quickLaunchNodes)
            {
                if (string.Compare(node.Title, groupName) == 0)
                {
                    quickLaunchNodes.Delete(node);
                    web.Update();
                    break;
                }
            }
        }

        Add Quick launch link to a group-


        public static void AddQuickLaunchLink(SPWeb web, string groupName, string linkName, string linkUrl)
        {
            SPNavigationNodeCollection quickLaunchNodes = web.Navigation.QuickLaunch;
            foreach (SPNavigationNode node in quickLaunchNodes)
            {
                if (string.Compare(node.Title, groupName) == 0)
                {
                    SPNavigationNode linkNode = new SPNavigationNode(linkName, linkUrl, true);
                    node.Children.AddAsFirst(linkNode);
                    web.Update();
                    break;
                }
            }
        }

        Remove quick launch link from a group-


        public static void RemoveQuickLaunchLink(SPWeb web, string groupName, string linkName)
        {
            SPNavigationNodeCollection quickLaunchNodes = web.Navigation.QuickLaunch;
            foreach (SPNavigationNode node in quickLaunchNodes)
            {
                if (string.Compare(node.Title, groupName) == 0)
                {
                    foreach (SPNavigationNode nodeChild in quickLaunchNodes)
                    {
                        if (string.Compare(nodeChild.Title, linkName) == 0)
                        {
                            node.Children.Delete(nodeChild);
                            web.Update();
                            break;
                        }
                    }
                }
            }
        }

Add field to default view in SharePoint List

SPView view = list.DefaultView;
view.ViewFields.Add(fieldName);
view.Update();

Create a Lookup field in SharePoint list

/// <summary>
/// Adds the lookup field to list.
/// </summary>
/// <param name="web">The web.</param>
/// <param name="list">The list.</param>
/// <param name="fieldName">Name of the field.</param>
/// <param name="lookupListName">Name of the lookup list.</param>
/// <param name="lookupFieldName">Name of the lookup field.</param>

SPField AddLookupFieldToList(SPWeb web, SPList list, string fieldName, string lookupListName, string lookupFieldName)
        {
            SPList destList = web.Lists[lookupListName];
            list.Fields.AddLookup(fieldName, destList.ID, required);
            SPFieldLookup field = list.Fields[fieldName] as SPFieldLookup;
            field.LookupField = destList.Fields[lookupFieldName].InternalName;
            field.Update(true);
            return field;
        }

Create a User field in SharePoint List

SPList list;

list.Fields.Add(fieldName, SPFieldType.User, required);
SPFieldUser field = list.Fields[fieldName] as SPFieldUser;
field.SelectionMode = SPFieldUserSelectionMode.PeopleOnly;
field.AllowMultipleValues = false;
field.Presence = true;
field.Update(true);