Monday, November 16, 2009

SharePoint Online

This comes in two offerings:

Standard Offering

Dedicated Offering

Multiple customers share a common infrastructure

Each customer has its own infrastructure

Customer priority: rapid deployment

Customer priority: heavy customization

No lower seat limit

For customers with more than 5000 seats

Cost efficiency optimized for customers with up to 20,000 users

Optimized for customers with 20,000+ users

The dedicated offering support custom code including SharePoint Packages

For developing on SharePoint Online Services, check this white paper which describes the customization (or extensibility) capabilities that are supported with the Standard offering of SharePoint Online-

Microsoft SharePoint Online Standard Developer Guide (http://www.microsoft.com/downloads/details.aspx?familyid=d007f35e-375c-4b11-bc40-bc9082bb224a&displaylang=en&tm)

Microsoft Online Services

Seeing the prospect and future in cloud computing, Microsoft have moved rapidly in BPOS(Business Productivity Online Suite). This Suite contains of:

  • SharePoint Online
  • Exchange Online
  • Office Communicator Online
  • Office Live meeting

The next product to add to this suite would be Dynamics CRM. Having SharePoint online using Microsoft Live services is a great initiate as this would help to target small to medium customer. These customer who wants to have a presence on web would vastly benefit from this cost effective, secure and reliable server.

For more details check http://www.microsoft.com/online/default.mspx and try 30 days trial

Follow the Microsoft Online Service team on their blog at http://blogs.technet.com/msonline/default.aspx

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);

Tuesday, June 23, 2009

The selection of directory service properties is disabled because the portal is in an untrusted domain

In User Profile, I was unable to modify any user property mapping due to missing Data Source field dropdown. There was no question of untrusted domain as I am using only one active directory and SharePoint was able to import from that. I finally managed to fix these by following these steps:

  • Goto to Profile and Import Settings
  • Click View Import Connections
  • Click on Existing Import Connection and select edit
  • In Authentication Information section, make sure the account is SharePoint Admin Domain account and not the default account
  • Click Ok and you should now able to see mapping data source drop down

Tuesday, April 07, 2009

Delete a Web Part in SharePoint

If you are planning to remove a web part from a page, ALWAYS click on Delete menu rather than pressing the X button. Clicking on X button would close the web part and you will receive a warning in your servers event log. The web part is not actually deleted from the page, it is removed from the Visible area of the page and placed in the Web Part Page Gallery.

You can delete a CLOSED web part  by using the Web Part Maintenance page. Browse to http://www.yourserver.com/yoursite/yourpage.aspx?contents=1

You could see the web part that has been closed. Now, delete it by selecting the checkbox and pressing Delete

Accessing Current User in MOSS

You could get the current user in SharePoint by calling the following code:

SPUser user = SPContext.Current.Web.CurrentUser;

But to access the current user inside the code running under Elevated Privileges, open new reference to SPSite.

SPSecurity.RunWithElevatedPrivileges(delegate()

{
    using (SPSite site = new SPSite(“http:\\MOSS_SITE”))

{
      using (SPWeb web = site.OpenWeb())

          SPUser user =SPContext.Current.Web.CurrentUser;

    }

}
);

The above code will switch the user context and now, you would get the user under which application pool is running

Mystery of SharePoint\System Account

When you run your code with Elevated Privileges, the code runs under the identity of the hosting application pool. SharePoint\System account exists ONLY within content of SharePoint runtime(not recognised by Windows Security subsystem) and map internally to the account under which application pool is running.

If you are running application pool under DOMAIN\SSUSER account, the code is still audited as running under SharePoint\System account. So, if you get access error on SharePoint site stating that SharePoint\System account don’t have access to the resource, this is because the application pool identity account don’t have access to the resource. Don’t spend time looking for SharePoint\System account :-)

Friday, April 03, 2009

Set Manager Profile property value

To assign manager from one profile to another, you could not set it directly. You need to convert the Source Manager profile to a UserProfile object and then assign the account name to the destination profile manager’s property.

UserProfileManager upManager;
UserProfile sourceProfile,
destProfile;

string managerId = sourceProfile["manager"].Value.ToString();

if (upManager.UserExists(managerId))

{

UserProfile managerProfile = upManager.GetUserProfile(managerId);

destProfile["manager"].Value = managerProfile["Accountname"].Value;

}