Tuesday, December 27, 2011

The transaction log for database 'SharePoint_Config' is full

Scenario: Tried to change web application settings from Authentication Providers page from Central Administration

Problem: Received the error "The transaction log for database 'SharePoint_Config' is full" when tried to save the updated settings.

Resolution: Found that the drive that containing the config database log is having very few space remaining.
Following steps helped to resolve this issue

1. Do full backups of all the SharePoint databases.  
2. Open the database, right click SharePoint Config database > Properties
3. Select Simple under Recovery model list > Click OK
4. Right click the database,  Tasks > Shrink > Files
5. In File type select Log
6. Click OK

Refer to the following post for more information

Monday, October 31, 2011

Your backup is from a different version of Windows SharePoint Services and cannot be restored to a server running the current version. The backup file should be restored to a server with version '12.0.0.6535' or later.

I tried to backup and restore a site collection from our production server to development. Our production is MOSS 2007 64 bit and Development is MOSS 2007 32 bit.

I got the following error when tried to restore the backed up file

"Your backup is from a different version of Windows SharePoint Services and cannot be restored to a server running the current version. The backup file should be  restored to a server with version '12.0.0.6535' or later."

When I checked the version of each SharePoint site Site Actions > Site Settings, both had different versions. In order to have a successful restoration, we need to sync both the SharePoint versions.

Site Version

We were having version 12.0.0.6535 in production and 12.0.0.6421 in development.


I have fixed the issue by installing KB983444 which brought the MOSS 2007 to version 12.0.0.6535.
Run the Config wizard after  patch/hotfix/kb applied.

I'm able to use stsadm to restore from my backup into the new MOSS 2007 site.

Reference:
http://technet.microsoft.com/en-us/security/bulletin/MS10-039

http://www.microsoft.com/downloads/details.aspx?familyid=3841ceda-d0af-4e5e-8a1a-7dd954850783

Monday, October 24, 2011

The file '/_Layouts/Bamboo.ProjectPortfolioDashboard/HandleDataForCharts.ashx' does not exist.


Issue: We have installed the Bamboo's Project Portfolio Dashboard solution in our production environment without any issues, however, when we add the Web Part, the images in the Web Part were not loaded and getting the following error

The file '/_Layouts/Bamboo.ProjectPortfolioDashboard/HandleDataForCharts.ashx' does not exist. at System.Web.UI.Util.CheckVirtualFileExists(VirtualPath virtualPath) at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.UI.SimpleHandlerFactory.System.Web.IHttpHandlerFactory2.GetHandler(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath) at System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig) at System.Web.HttpApplication.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

Note: Our SharePoint site is SSL enabled. The WebPart is working in http and not on Https. When contacted Bamboo we have been told that the issue is not with their setup and it is with our environment.

Resolution: We checked that the file HandleDataForCharts.ashx does exist at the _layouts folder. We finally found out that an HttpHandler entry is missing in the web.config file

We were able to  resolved the issue by adding the following web.config entry under <httpHandlers> section

<add verb="*" path="*.ashx" type="Bamboo.HandleDataHelper.HandleDataForCharts" validate="false" />

The following link http://msdn.microsoft.com/en-us/library/bb515343.aspx helped us to resolve the issue

Friday, September 30, 2011

Create multi level approval workflow in SharePoint 2010 using Visual Studio


Requirement: We have a requirement to create a Multi-level approval workflow for document libraries. I need to use SharePoint groups for each level of approval/review as there are multiple users need to review the document and approve and don't want to hard code the SharePoint groups. Can we create a custom workflow section where I can set the 'level of approvals' and 'Approvers' for each level when assigning a workflow for a document library

Solution: Create a workflow association page using VS.NET 2008. Refer to my previous post for more info.

Attached the screen shots of final output
Page 1:
Create Multi-level Approval Workflow

Page 2:
Create Multi-level Approval Workflow

The codebehind page of the association page (aspx page) will have the code to create SharePoint groups for "Reviewers"(1st level approval) and "Approvers"(2nd level approval) on submit. All the workflow related activities is handled in the Workflow coding.



Trigger event when workflow is added to a document library

Requirement:  I've created a custom sequential workflow using Visual studio and wanted to create SharePoint group when the workflow is added to a document library.

Issue: There is no event or activity associated to the Workflow which will be triggered when we add a Workflow to a document library of list. Also there is no event associated with document library or list that to be triggered when a workflow is added to it.

Solution: Create an association and initiation form in a workflow using VS.NET 2008. You can use either .aspx or InfoPath forms in a workflow. Association and initiation forms are displayed for users to complete before any workflow actually starts.Association forms are displayed to administrators when they first decide to add or associate a workflow with a particular list, document library, or content type. You can use association forms to let an administrator specify parameters, default values, and other information for the workflow as it applies to items on the list, library, or content type with which the administrator is associating it.

Below are some excellent resource I referred to and implemented successfully. Please refer to
http://msdn.microsoft.com/en-us/library/cc297199(v=office.12).aspx

Workflows for WSS3 Demystifying ASPX forms association

http://sergeluca.wordpress.com/2008/11/20/step-by-step-tutorial-creating-workflows-with-windows-sharepoint-services-and-moss-2007-part-1420-easy-aspx-association-forms-my-small-generic-framework/


Sunday, August 28, 2011

Insert a Sharepoint list item from web services


The following code is used to insert an item to a list using SharePoint Web Services.

        /// <summary>
        /// Method to insert picture URL to a list
        /// </summary>
        /// <param name="pictureURL">URL of the picture</param>
        /// <param name="currentlLoginID">Current logged in user</param>
        private void InsertItem(string pictureURL,string currentlLoginID)
        {
 
       /*Declare and initialize a variable for the Lists Web service.*/
            spsService.Lists listService = new spsService.Lists();

            /*Authenticate the current user by passing their default
            credentials to the Web service from the system credential cache.*/
            listService.Credentials = System.Net.CredentialCache.DefaultCredentials;
                 
            listService.Url = "http://spsService/sites/MP/_vti_bin/Lists.asmx";

            System.Xml.XmlNode ndListView = listService.GetListAndView("Team Profiles", "");
            string listName = ndListView.ChildNodes[0].Attributes["Name"].Value;
            string viewName = ndListView.ChildNodes[1].Attributes["Name"].Value;


             XmlDocument xmlDoc = new XmlDocument();
         
            /* Declare an XmlNode object and initialize it with the XML response from the GetListItems method.*/
            System.Xml.XmlNode nodeListItems = listService.GetList(listName);

            string sBatch = string.Empty;        
            string uid = "-1;#" + currentlLoginID;

            //Query to insert data
            sBatch = "<Method ID=\"1\" Cmd=\"New\">";
            sBatch += "<Field Name=\"ID\">New</Field>";
            sBatch += "<Field Name=\"User_Picture\">" + pictureURL + "</Field>";
            sBatch += "<Field Name=\"UID\" >" + uid + "</Field>";
            sBatch += "</Method>";

            XmlElement batch_element = xmlDoc.CreateElement("Batch");
            batch_element.SetAttribute("OnError", "Continue");
            batch_element.SetAttribute("ViewName", viewName);

            batch_element.InnerXml = sBatch;
            listService.UpdateListItems(listName, batch_element);
        }

Wednesday, August 17, 2011

List all SharePoint Databases

Before migrating/moving the SharePoint database, we need to find all the database name.

We may need to find move the following database


Databases for Shared Services Providers (SSPs)
Search databases for SSPs
Content databases
Search database
Central Administration content database
Configuration database

To find all the SP database names, Go to Central Administration >> Operations >> Perform a Backup. This will take you to the page with all database listed.

Monday, August 15, 2011

Cannot find ContentPlaceHolder 'PlaceHolderPageTitle' in the master page '~masterurl/default.master', verify content control's ContentPlaceHolderID attribute in the content page

Error: "An unexpected error has occurred" in almost all the list and document library pages in SharePoint site

Cause: Changed the master page from SharePoint designer by right clicking the master page file and selecting "Set as default master page".

Resolution: By updating the callstack=true in web.config file of the web application, we got more detailed error message

Cannot find ContentPlaceHolder 'PlaceHolderPageTitle' in the master page '~masterurl/default.master', verify content control's ContentPlaceHolderID attribute in the content page


Opened the master page in the SharePoint designer and noticed that the PlaceHolderPageTitle is missing.
So replaced the below line
<Title>Our Company Intranet</Title>
with
<Title ID=onetidTitle><asp:ContentPlaceHolder id=PlaceHolderPageTitle runat="server"/></Title>


and save the master page.

Saturday, July 30, 2011

Trim the text in the multiple line of text field in a list and add a tool tip using SharePoint Designer 2007


1. This is the sample list which is currently displaying full text from multiple line of text field “Remarks"
Multiline of text

2. Open the site in SharePoint designer , navigate to the list default view page.(In this example we are using AllItems.aspx page)

3. Right click on the List View Web Part and select “Convert to XSL T Data View”. This will automatically convert settings for the current view into data view parameters.
Convert to XSLT DataView

4. After converting to XSLT, select the remarks field and switch to code view, you will see the code to display the remarks field as below

<TD Class="{$IDAWNV5H}"><div dir="{ddwrt:GetVar('Direction')}">
<xsl:value-of disable-output-escaping="yes" select="@remarks" />
</div></TD>

 We need to change the above line of code as below

<TD Class="{$IDAXNQ1G}" style="height: 22px">
<div dir="{ddwrt:GetVar('Direction')}" title="{@remarks}">
<xsl:choose >
<xsl:when test="@remarks != ''" >
<xsl:value-of disable-output-escaping="yes" select='concat((substring(@remarks,1,20)),"...")' />
</xsl:when>
<xsl:otherwise>
<xsl:value-of disable-output-escaping="yes" select="@remarks" />
</xsl:otherwise>
</xsl:choose>
</div></TD>

 5. Save the file. Now you will see the trimmed text in the default view page

Trim multi-line of text column

Monday, July 11, 2011

Error: The search request was unable to connect to the Search Service

Scenario: Recieved an error in our SharePoint site when we try to search contents

Error message: "The search request was unable to connect to the Search Service"

Resolution: 

1. Go to Central Admin > Operations > Services on Server > Office SharePoint Server Search Service
Make sure the "Use this server for serving search queries" is checked.

2. Also verify that the search account is configured in both search services
Go to Central Admin > Operations > Services on Server > Office SharePoint Server Search service
Go to Central Admin > Operations > Services on Server > Windows SharePoint Services Search

3. Make sure the search account specified in "Default content access account" is used on above settings.

Saturday, July 2, 2011

Create subsite programmatically when a new item is created in a SharePoint list

Code snippet to create sub site when a new item in list. Create a feature and bind this event handler to itemadding event.

public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);

string sitename = string.Empty;
string newSiteURL = string.Empty;
string siteShortName = string.Empty;
string strTemplateName = "Blank Site Template";

try
{
sitename = properties.AfterProperties["Title"].ToString();
siteShortName = GetAcronym(sitename.Trim());

if (properties.ListTitle == "Projects")
{
SPWeb website = properties.OpenWeb();
website.AllowUnsafeUpdates = true;

using (SPSite site = website.Site)
{
//to check if the site name/URL already exists
SPWeb web = site.AllWebs[website.ServerRelativeUrl + "/" + siteShortName];
int i = 0;

//if site exists, loop through with appending number at the end of site URL
while (web.Exists)
{
i = i + 1;
web = site.AllWebs[website.ServerRelativeUrl + "/" + siteShortName + i];
}

if (i != 0)
{
siteShortName = siteShortName + i;
}

//Create subsite
newSiteURL = CreateSubSite(website.Url, siteShortName, sitename, strTemplateName);

//Updating the sub site URL in the list's URL field
if (!string.IsNullOrEmpty(newSiteURL))
{
properties.AfterProperties["URL"] = newSiteURL;
}
website.AllowUnsafeUpdates = false;
web.Dispose();
}
}
}
catch (Exception ex)
{
//handle exception
}
}


/// [summary]
/// Method to create subsite
/// [summary]
/// [param name="parentSiteURL"]Parent site URL [param]
/// [param name="siteURLRequested"]site name acronym to be appended in subsite URL [param]
/// [param name="siteTitle"]Site Name [param]
/// [param name="siteTemplateName"]Site Template Name [param]
/// [returns]site URL [returns]
private string CreateSubSite(string parentSiteURL, string siteURLRequested, string siteTitle, string siteTemplateName)
{
const Int32 LOCALE_ID_ENGLISH = 1033;
string newSiteURL = string.Empty;
try
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite siteCollection = new SPSite(parentSiteURL))
{
using (SPSite site = new SPSite(parentSiteURL))
{
using (SPWeb parentWeb = site.OpenWeb())
{
SPWebTemplateCollection Templates = parentWeb.GetAvailableWebTemplates(Convert.ToUInt32(LOCALE_ID_ENGLISH));
SPWebTemplate siteTemplate = Templates[siteTemplateName];

//create subsite
using (SPWeb newSite = parentWeb.Webs.Add(siteURLRequested, siteTitle, "", Convert.ToUInt32(LOCALE_ID_ENGLISH), siteTemplate, false, false))
{
if (!string.IsNullOrEmpty(newSite.Url))
newSiteURL = newSite.Url.ToString();
}
}
}
}
});
return newSiteURL;
}
catch (Exception ex)
{
//handle exception
}
}


/// summary>
/// Function to get the acronym of the site name
/// summary>
/// [param name="strSiteName"]Site Name [param]
/// [returns]acronym value[/returns]
private string GetAcronym(string strSiteName)
{
string shortName = string.Empty;
string[] txtArray = strSiteName.Split(' ');
try
{
//if site name is a single word, get the first three characters of the site name
if (txtArray.Length == 1)
{
return strSiteName.Substring(0, 3);
}

//Get the first letter of each word in the site name
foreach (string word in txtArray)
{
shortName += word.Substring(0, 1);
}
return shortName;
}
catch (Exception ex)
{
// handle exception
}
}

Friday, July 1, 2011

SharePoint Useful CodePlex Tools for SharePoint

To manage where the column are displayed (e.g.: new or edit mode). To Hide columns from newform.aspx, editform.aspx and dispform.aspx etc
http://wsslistconfigurator.codeplex.com/

To add 'Only their own' permission for the document library.
http://moresharepoint.codeplex.com/

Ad Rotator WebPart
http://spadrotator.codeplex.com/

Caml Query Builder
http://spcamleditor.codeplex.com

JQuery SPServices
http://spservices.codeplex.com

Hit Counter WebPart
http://hitcounter.codeplex.com/

Cascading drop downs
http://customfieldcontrols.codeplex.com/
http://cascddlistwithfilter.codeplex.com/

To manage alerts on list or item for SharePoint groups.
http://advancedalert.codeplex.com/

Useful Sharepoint Designer Custom Workflow Activities
http://spdactivities.codeplex.com/wikipage?title=Copy%20List%20Item%20Extended%20Activity&ProjectName=spdactivities

SharePoint User Change Password
http://userchangepassword.codeplex.com/

List of users and their access
http://accesschecker.codeplex.com/

SharePoint Navigation Menu
http://spnavigationmenu.codeplex.com/

Tuesday, June 14, 2011

Filter data in a DataView Web Part using SharePoint Designer


Follow the steps to filter the Overall Project Status by its Status, Assume that we need to list all the project that are in open status.

  1. Open the page that contains the Data View that you want to filter.
  2. Right-click the Data View, and then click Show Common Control Tasks on the shortcut menu.
  1. In the Common Data View Tasks list, click Filter.
  2. In the Filter Criteria dialog box, click Click here to add a new clause.
  3. Select more fields from Field Name drop downFilter in DataView WebPart
  4. Select the field Status field and Click Ok
  5. Enter the value as Open in the Value field and click OK
  6. Apply Filter in DataView WebPart
  7. Save the file and refresh the page to verify the webpart.

Thursday, June 2, 2011

Check if a folder exists in a SharePoint List


Below code is to check if the folder already exists in a SharePoint List.


 private void CreateFolderInList(string folderName, string listName, SPListCollection listCollection)
        {
            try
            {
                //Creating folder in "Sites" Lists
                SPList list = listCollection[listName];

                //Check if the Folder is already available in the list
                SPQuery query = new SPQuery();
                query.Query = "<Where><And><Eq><FieldRef Name='Title'/><Value Type='Text'>" + folderName + "</Value></Eq><Eq><FieldRef Name=’FSObjType’/><Value Type=’Lookup’>1</Value></Eq></And></Where>";

  query.ViewAttributes = "Scope=\"RecursiveAll\""


                //Retrieve the items based on Query
                SPListItemCollection items = list.GetItems(query);

  //Item count is "0" if the folder does not exist
                if (items.Count == 0)
                {
                    folderItem = list.Items.Add(list.RootFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder);
                    folderItem["Title"] = folderName;
                    folderItem.Update();
                    //return folderItem.Url;
                }
            }
            catch (Exception ex)
            {
               

            }
}

Prevent duplicate item in a SharePoint List

The following Event Handler code will prevent users from creating duplicate value in  "Title" field.

ItemAdding Event Handler

 public override void ItemAdding(SPItemEventProperties properties)
        {
            base.ItemAdding(properties);
            if (properties.ListTitle.Equals("My List"))
            {
                try
                {
                    using(SPSite thisSite = new SPSite(properties.WebUrl))
                    {
                        SPWeb thisWeb = thisSite.OpenWeb();
                        SPList list = thisWeb.Lists[properties.ListId];
                        SPQuery query = new SPQuery();
                        query.Query = @"<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + properties.AfterProperties["Title"] + "</Value></Eq></Where>";
                        SPListItemCollection listItem = list.GetItems(query);
                        if (listItem.Count > 0)
                        {
                            properties.Cancel = true;
                            properties.ErrorMessage = "Item with this Name already exists. Please create a unique Name.";
                        }
                    }
                }
                catch (Exception ex)
                {
                    PortalLog.LogString("Error occured in event ItemAdding(SPItemEventProperties properties)() @ AAA.BBB.PreventDuplicateItem class. Exception Message:" + ex.Message.ToString());
                    throw new SPException("An error occured while processing the My List Feature. Please contact your Portal Administrator");
                }
            }
        }


Feature.xml


<?xml version="1.0" encoding="utf-8"?>
<Feature  Id="1c2100ca-bad5-41f5-9707-7bf4edc08383"
          Title="Prevents Duplicate Item"
          Description="Prevents duplicate Name in the "My List" List"
          Version="12.0.0.0"
          Hidden="FALSE"
          Scope="Web"
          DefaultResourceFile="core"
          xmlns="http://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="elements.xml"/>
  </ElementManifests>
</Feature>

Element.xml


<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Receivers ListTemplateId="100">
    <Receiver>
      <Name>AddingEventHandler</Name>
      <Type>ItemAdding</Type>
      <SequenceNumber>10000</SequenceNumber>
      <Assembly>AAA.BBB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8003cf0cbff32406</Assembly>
      <Class>AAA.BBB.PreventDuplicateItem</Class>
      <Data></Data>
      <Filter></Filter>
    </Receiver>
  </Receivers>
</Elements>

The source code of this feature is available at Technet Gallery

Friday, May 27, 2011

Email the Approval Status to "Created By"/"Modified By" user from Visual Studio workflow

Below is the code snippet to send an email about the approval status to the user who submitted/created the list item in a SharePoint list. Assume that the Visual studio workflow is attached to the list and will trigger the workflow when the item is edited in the list.


  if (workflowProperties.Item.ModerationInformation.Status == SPModerationStatusType.Denied)
  {
        StringDictionary headers = new StringDictionary();
        headers.Add("from", "administrator@domain.com");
        headers.Add("subject", "Request - Denied");
        headers.Add("content-type", "text/html");
        System.Text.StringBuilder strMessage = new System.Text.StringBuilder();

       //link to list item display form (view item)
       strMessage.Append("The request submitted in ABC site has been rejected."+ workflowProperties.WebUrl+ "/" + workflowProperties.List.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url + "?ID=" + workflowProperties.ItemId);
        strMessage.Append("<br><br> Approver's comments: "+ workflowProperties.Item.ModerationInformation.Comment);

        SPListItem item = workflowProperties.Item;
        SPUser spUser = GetSPUser(item, "Created By");
        if (!String.IsNullOrEmpty(spUser.Email))
        {
                 headers.Add("to", spUser.Email);
                 SPUtility.SendEmail(web, headers, strMessage.ToString());
        }
  }

//Function to get the user instance who submitted the item
  private SPUser GetSPUser(SPListItem item, string fieldName)
        {
            SPFieldUser field = item.Fields[fieldName] as SPFieldUser;
            if (field != null && item[fieldName] != null)
            {
                SPFieldUserValue fieldValue = field.GetFieldValue(item[fieldName].ToString()) as SPFieldUserValue;
                if (fieldValue != null)
                {
                    return fieldValue.User;
                }
            }
            return null;
        }

Tuesday, May 24, 2011

Limited Access permission in SharePoint

Scenario: We have a list which doesn't inherit permissions from the site. Also, at the root of the list, there are folders, which are also set to NOT inherit permissions from the parent folder (which is the root of the list). We have added a Site group to the folder with 'Contribute' permission.

Issue: We see that the site group which we added to the folder is also added automatically at list level as well. The group have “Limited Access” permissions to the list.

Explanation: When you set permissions (for example: Full Control/Contribute) to the Folder after you break the permissions inherit. The users\group will have “Limited Access” permissions to the list, not the same permissions with the folder.

As discussed on "Anonymous Users, Forms Pages, and the Lockdown Feature  "  on Microsoft Enterprise Content Management (ECM) Team Blog  :   
   
In SharePoint, anonymous users’ rights are determined by the Limited Access permission level. Limited Access is a special permission level that cannot be assigned to a user or group directly. The reason it exists is because if you have a library or subsite that has broken permissions inheritance, and you give a user/group access to only that library/subsite, in order to view its contents, the user/group must have some access to the root web. Otherwise the user/group will be unable to browse the library/subsite, even though they have rights there, because there are things in the root web that are needed to render the site or library. Therefore, when you give a group permissions only to a subsite or library that is breaking permissions inheritance, SharePoint will automatically give Limited Access to that group or user on the root web.

Source:
More information about “Limited Access” permissions:
http://office.microsoft.com/en-us/windows-sharepoint-services-help/permission-levels-and-permissions-HA010100149.aspx
http://paulgalvinsoldblog.wordpress.com/2008/11/02/what-is-limited-access-anyway/

Monday, May 23, 2011

Send an email with html format using SPUtility.SendEmail

SPWeb oWeb = SPContext.Current.Web

StringDictionary headers = new StringDictionary();

headers.Add("from",  "system@domain.com");
headers.Add("to", spUser.Email);
headers.Add("subject", "Welcome to the SharePoint group: ABC site: ");
headers.Add("content-type", "text/html"); //This is the default type

System.Text.StringBuilder strMessage = new System.Text.StringBuilder();                  
strMessage.Append("<br><br><b>Login Instructions: </b><br>");
strMessage.Append("<font color='red'><UL><li>If you are a US employee ALWAYS login in using the following login format </font><br>");

SPUtility.SendEmail(web, headers,strMessage.ToString());

Tuesday, May 17, 2011

Programmatically set permissions to a folder in a SharePoint list

This method can be used to bind permission to a folder in a SharePoint list

 /// <summary>
/// Method to set the permission at folder level for the newly created site groups
/// </summary>
/// <param name="web">The current web instance</param>
/// <param name="groupName">Name of the Site group that is added to the folder</param>
/// <param name="listName">Name of the list</param>
/// <param name="folderName">Name of the folder in the list</param>
/// <param name="role">Role/permission level set to the group to access folder for the site group users</param>

 private void SetRoleDefinitionBinding(SPWeb web,string groupName, string listName, string folderName, string role)
        {
            try
            {
                SPRoleAssignment roleAssignment = new SPRoleAssignment((SPPrincipal)web.SiteGroups[groupName]);
                SPList list = web.Lists[listName];
                SPQuery query = new SPQuery();
                    query.Query = "<Where><Eq><FieldRef Name='Title'/><Value Type='Text'>" + folderName + "</Value></Eq></Where>";
                //Retrieve the items based on Query
                SPListItemCollection items = list.GetItems(query);
               
                //Get the name and Url for the folder
                foreach (SPListItem item in items)
                {
                    SPFolder folder = web.GetFolder(item.Url);
                    folder.Item.BreakRoleInheritance(true);
                    roleAssignment.RoleDefinitionBindings.Add(web.RoleDefinitions[role]);
                    folder.Item.RoleAssignments.Add(roleAssignment);
                    web.Update();
                }
      
            }
            catch (Exception ex)
            {
              
                //Error handling
            }
        }

Tuesday, May 10, 2011

Activity 'onWorkflowActivated1' validation failed: Cannot resolve Activity 'Workflow1'

I got following error when I try to build custom workflow in Visual Studio 2008
"Activity 'onWorkflowActivated1' validation failed: Cannot resolve Activity 'Workflow1'"

To resolve this, do a search in your entire project and find  any references to "Workflow1", if so, rename all the occurrences with the modified class name.

Friday, May 6, 2011

"Save library as template" link is missing in SharePoint site

Some of the document libraries and list, "Save library as template" link is hidden by default. If you go to  "View All Site Content" and have a look at the description next to each library/list, the description that says "This system library was created by the Publishing feature.." will have the "Save library as template" link hidden.

This behaviour is by default, however we have a workaround for this. Go to the "Document Library Settings" page. You should see the URL address like this ".../listedit.aspx?List={GUID}", change the "listedit" to "savetmpl" and the URL look like this "../savetmpl.aspx?List={GUID}", now you will be able to save the library as a template.

This method is not recommended, but it works. If you have any workflow bound to the library then you may have some issues,but works fine if you just want to create a template for document settings, Columns and views.

Thursday, May 5, 2011

To prevent users from creating folders in SharePoint document libraries

Using SharePoint 2007;

The OOB method to remove the "New Folder" menu will prevent users only creating folder from the standard view and users are still be able to upload/create folders from explorer view. Below is the feature code used to prevent users from creating folders in document library even in explorer view.

Feature.xml

<?xml version="1.0" encoding="utf-8"?>
<Feature  Id="62b28298-e3fc-4ccc-a2ea-3f92b7e9a21e"
          Title="Disable Folders"
          Description="Feature to disable creating new folders in document libraries in the site"
          Version="12.0.0.0"
          Hidden="FALSE"
          Scope="Web"
    ActivateOnDefault="FALSE"
          DefaultResourceFile="core"
          xmlns="http://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="elements.xml"/>
  </ElementManifests>
</Feature>


Elements.xml

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
 <Receivers ListTemplateId="101">
  <Receiver>
   <Name>AddingEventHandler</Name>
   <Type>ItemAdding</Type>
   <SequenceNumber>10000</SequenceNumber>
   <Assembly>AAAA.BBB.AllUsers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5</Assembly>
   <Class>AAAA.BBB.AllUsers.DisableFoldersInLib</Class>
   <Data></Data>
   <Filter></Filter>
  </Receiver>
 </Receivers>
</Elements>

Code:
 public override void ItemAdding(SPItemEventProperties properties)
        {
            base.ItemAdding(properties);
            //If the new created file type is "folder" then the following conditions will be true
            if ((properties.BeforeUrl != properties.AfterUrl &&
                properties.ListItem == null &&
                properties.ListItemId == 0) ||
                properties.AfterProperties["ContentType"].ToString() == "Folder")
            {
                properties.Cancel = true;
                properties.ErrorMessage = "You are not allowed to create new Folders in this document library. Please tag the files with Metadata instead of creating folders.";
            }
        }

The source code of this feature is available at Technet Gallery

Thursday, April 14, 2011

Parent child relationship for lists in SharePoint

If you are looking for a project/child relationship for a Projects and Tasks list.  You can try using the
Budgeting and Tracking Multiple Projects Template which is part of the SharePoint "Fantastic 40" Site Templates. Basically this template allows you to track all your projects and tasks. When you view the project item, you also get a Related tasks, Related issues and Related milestones data views on the same page.Any tasks, issues or milestones you add on this page will be associated with that particular project and will rollup onto a nice looking dashboard.

Refer to the following URL to download the template.
http://www.microsoft.com/downloads/en/details.aspx?FamilyId=04FDA604-BAB0-4E43-8B88-38101DFE121A&displaylang=en

Refer to the following site which is created using this template.
http://demo.sharesquared.com/PTPM/BTMP/default.aspx


In case if you want any extra customization, you can customize this site and save as a template to reuse it.

Thursday, March 31, 2011

Move SharePoint Site Collection as a Subsite

Environment: SharePoint 2007/2010/2013

Requirement: To move a site collection as a subsite to another site collection, we can make use of STSADM or Powershell import/export command.

Following are the steps to achieve this

Assume that, we need to move the site collection http://sitecollection1/sites/asite to another site collection http://sitecollection2/sites/bsite as a subsite.


Steps

1. Export the site collection (http://sitecollection1/sites/asite) using STSADM command line tool

using stsadm command
stsadm.exe -o export -url http://sitecollection1/sites/asite -filename c:\backups\sc_asite.bak –includeusersecurity –nofilecompression

using powershell
Export-SPWeb -Identity http://sitecollection1/sites/asite -Path C:\backups\sc_asite.bak -IncludeUserSecurity -NoFileCompression

2. Create a new site with Blank Site template in the other site collection (http://sitecollection2/sites/bsite). Assume the blank site name is csite

3. Import the backed up site collection in c:\mybckup\sc_asite.bak

using stsadm command
stsadm.exe -o import -url http://sitecollection2/sites/bsite/csite -filename c:\backups\sc_asite.bak 
-includeusersecurity -nofilecompression

using powershell
Import-SPWeb http://sitecollection2/sites/bsite/csite  -Path c:\backups\sc_asite.bak -IncludeUserSecurity -NoFileCompression


After migration, the site collection 1 will be available under the following URL as a subsite http://sitecollection2/sites/bsite/csite



Tuesday, March 29, 2011

Unable to cast object of type 'XXXXXXXX' to type 'Microsoft.SharePoint.SPFeatureReceiver'

I got the following error on deployment
"Unable to cast object of type  XXXX.YYYYY' to type 'Microsoft.SharePoint.SPFeatureReceiver'

Resolution:
Removed the following entries ReceiverAssembly & ReceiverClass from feature.xml and the issue is resolved

ReceiverAssembly="XXXX.YYYYY' , Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5"
ReceiverClass="XXXX.YYYYY.ZZZZZ"

Friday, March 25, 2011

To provision a file in Pages document library

Below is the feature file that is used to upload a file in to Pages document library on feature activation

Feature.xml

<?xml version="1.0" encoding="utf-8"?>
<Feature  Id="21a53317-2fd7-4f21-b5c4-efc018b88154"
          Title="Add Site Users List Template "
          Description="Upload the 'All Site Users' list template to site collection"
          Version="12.0.0.0"
          Hidden="FALSE"
          Scope="Site"
    ActivateOnDefault="FALSE"
          DefaultResourceFile="core"
          ReceiverAssembly="xxxx.yyy.ListAllUsers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5"
          ReceiverClass="xxxx.yyy.ListAllUsers.AddGetUsersList"       
          xmlns="http://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="elements.xml"/>
   <ElementFile Location="webpartpage.aspx"/>
  </ElementManifests>
</Feature>

Elements.xml

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="Pages" Path="" Url="Pages">
<File Name="webpartpage.aspx" Url="webpartpage.aspx" IgnoreIfAlreadyExists="FALSE"/>
</Module>
</Elements>

Once the feature is activated the file is uploaded to the document library, however I cannot view the file in default view but able to view in the Explorer view, currently working on that

List all users and groups from SharePoint site collection

Environment: MOSS 2007                  Click here for SharePoint Online Version

The following code is to generate a list on all site collection users, their groups and subsite details

- I've created a custom list named "All Site Users" with  5 columns as User Name, Groups, Site URL, Account Name, TagUsers

- The list template is uploaded programmatically on feature activation, The below code is a webpart code, which is added to a webpart page on solution deployment, when the webpart page is accessed, the following code will loop through the users in the site collection their groups and log the details to the custom list "All Site Users".

-'TagUsers' column can be used to create a view to list unique user names, condition for the view would be Filter by TagUsers=1


SPWeb rootweb = null;
                SPSite SPSite = null;
                try
                {
                   using (SPSite = new SPSite(SPContext.Current.Site.ID))
                    {
                        using (rootweb = SPSite.OpenWeb())
                        {
                            //Delete and create a new Portal Users List with updates
                            DeleteListIfExists(rootweb, "Portal Users List");
                            SPListTemplateCollection templateCollection = SPSite.GetCustomListTemplates(rootweb);
                            SPListTemplate template = templateCollection["Portal Users List"];
                            rootweb.AllowUnsafeUpdates = true;
                            //Create the Portal Users List using the PortalUsersList.stp template,                            rootweb.Lists.Add("Portal Users List", "List to display all the site collection users and their groups", template);
                            //Getting the URL of the list
                            SPList alluserslist = rootweb.Lists["Portal Users List"];
                            string ListURL = alluserslist.DefaultViewUrl;
                            Hashtable htUsers = new Hashtable();
                            //Loop all the Sites
                            foreach (SPWeb SPWeb in SPSite.AllWebs)
                            {
                                //Get All users in the subsite
                                SPUserCollection AllSPWebUsers = SPWeb.AllUsers;
                                //Loop each users in the Web/subsite
                                foreach (SPUser user in AllSPWebUsers)
                                {
                                    //Adding the user to the "Portal Users List" list
                                    SPListItem newItem = alluserslist.Items.Add();
                                    SPGroupCollection AllGroups = user.Groups;
                                    //AllGroups.Count is '0' when the users are directly added to the site
                                    if (AllGroups.Count == 0)
                                    {
                                        newItem["User Name"] = user.Name;
                                        newItem["Account Name"] = user.LoginName;
                                        newItem["Parent Site"] = SPWeb.Url;
                                        newItem["Group"] = "Individual User";
                                       
                                        if (!htUsers.Contains(user.LoginName))
                                        {
                                            newItem["TagUsers"] = 1;
                                            htUsers.Add(user.LoginName,user.Name);
                                        }
                                       
                                    }
                                    else
                                    {
                                        //Loop each group the user added to
                                        foreach (SPGroup group in AllGroups)
                                        {
                                            newItem["User Name"] = user.Name;
                                            newItem["Account Name"] = user.LoginName;
                                            newItem["Parent Site"] = SPWeb.Url;
                                            newItem["Group"] = group.Name;
                                            if (!htUsers.Contains(user.LoginName))
                                            {
                                                newItem["TagUsers"] = 1;
                                                htUsers.Add(user.LoginName, user.Name);
                                            }
                                        }
                                    }
                                    //Saving new item in the list
                                    newItem.Update();
                                }
                                alluserslist.Update();
                            }
                            //After WebPart process the entire users list, will be redirected to the "Portal Users List" page
                            SPUtility.Redirect(ListURL, SPRedirectFlags.Trusted, HttpContext.Current);
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    //Ignoring this as SPUtility.Redirect throws ThreadAbortException
                }
                   catch (Exception e)
                {
                 }
             }

Wednesday, March 9, 2011

InfoPath URL in Navigation

If you need to provide a navigation menu in SharePoint page with the InfoPath Form URL, your URL will be truncated if it is length exceeds 256 characters, to shorted the URL we can use


~sitecollection in the URL instead of "http://servername/site"


The full URL after change would be similar like below


https://servername/sites/sitename/_layouts/FormServer.aspx?XsnLocation=~sitecollection/sitename/InfoPathForms/rrtemplate.xsn&SaveLocation=~sitecollection/sitename/FormLibName&Source=~sitecollection/sitename/FormLibName/Forms/AllItems.aspx&DefaultItemOpen=1

Wednesday, March 2, 2011

URL properties used in SharePoint designer

Assume that https://server/sites/sitename/libraryname/formname.xml
  the value for the URL properties would be

Server Relative URL: /sites/libraryname/formname.xml
URL Path: /sites/sitename/libraryname/formname.xml

Wednesday, February 23, 2011

Tuesday, February 22, 2011

Publish InfoPath 2007 form in MOSS 2007

1. Design the form
2. Create a form library to store the source form template (xsn).
3. Create another form library to store all the submitted forms
4. Submit data to document library(step 2) on Submit option
5. Publish form to the form library (step 1)

Monday, February 21, 2011

Table border color always black in InfoPath table

To change the border color of a table in InfoPath

1. Right-click the table that you want to change the color.
2. Click Borders and Shading menu.
3. In Borders Tab, select the color that you want to apply for the table border from color palette.
4. Under Presets, click the button for the borders that you want. (NOTE: you need to click the preset button every time you change the color, otherwise the border color remains unchanged)
5. Click OK

Friday, February 18, 2011

Add Label Control in InfoPath

To add a dynamic label control in InfoPath 2007, we can use the Expression Box in Advanced Controls section.

For example, if you want to insert the current date as a dynamic label in the form,


1. Add Expression Box in the form
2. Insert function Date and Time --> Today
3. To change the Date format - Set the format under Result Section in General Tab of Expression Box Properties

Wednesday, February 16, 2011

Bind SharePoint list filtered data to Infopath dropdown

To bind a SharePoint list data in to a combo box in InfoPath
By default the values of a specific field in a list is bind based on the default view set in the list.

To bind the values based on a different view, below are the steps


1. Form the URL of the list and view
https:////_vti_bin/owssvr.dll?Cmd=Display&List=<YourListID>&XMLDATA=TRUE&View=<YourViewID&gt;

To get your list ID and View ID

List Settings --> Click on the View that you want to bind in the infopath drop down control

Your URL contains the List GUID and View GUID
https:///sites//_layouts/ViewEdit.aspx?List=%7B9B7BA6DE%2D0C1C%2D4832%2D8CC0%2DAF71EC3BAB46%7D&View=%7BF60E1186%2D394F%2D4BF3%2D96CD%2D0CC62C693D85%7D&Source=<>


2. Use the formed URL as your XML data source in InfoPath and your drop down data will be filtered as per your specific view
3. In InfoPath Data Connection Wizard, select XML document as your data source and provide the following URL as the XML data file

https:////_vti_bin/owssvr.dll?Cmd=Display&List=<YourListID>&XMLDATA=TRUE&View=<YourViewID>


XML Data source in Infopath

4. Create a data connection and set that to the drop down list in the InfoPath. Now the drop down will list the data based on your specific view