Wednesday, April 17, 2013

Get count of sites under a site collection uisng SharePoint Object Model

This article will describe a very simple way to calculate total no. of Sites inside a Site Collection. Below are the steps:

1. We first have to create a Uri object, which will capture the webapplication (SPwebApplication) URL. 

2. Then a Site Collection (SPSite) object can be created by selecting the appropriate site collection from the above web app.

3. Count the number of sites (SPWeb) in this site collection.

//Sample Code

Required Namespaces :

System
System.IO
Microsoft.SharePoint
Microsoft.SharePoint.Administration

       Uri u = new Uri("MyWebAppURL");
       
           SPWebApplication myWebApp= SPWebApplication.Lookup(u);
        
           SPSite siteColName;

           siteColName = myWebApp.Sites["sites/MySiteCol"];

          Console.WriteLine("Total number of sites under this site collection : "  +     siteColName.AllWebs.Count);

Multiple User Conflict in SharePoint: User changes after clicking ok in People Picker/Address book

This happened recently while I was trying to add a user on a SharePoint Site. User A was replaced with User B.


Problem

  • While searching for a user in Address book by typing the name, say "User A", it shows the correct user. But once the user is added by clicking OK, it changes to say "User B". 
  • When searching the user by domain\username (for User A), it only shows two occurrences of "User B".
  • There is only a single letter difference between both of their usernames. E.g : For UserA- domain\samename1, For UserB-domain\samename


Solution:

  • Check in   /_catalogs/users/simple.aspx. Delete both the users from it.
  • Run both full and incremental import of user profiles in SSP.
  • After this, try adding the user again.

Root Cause:

  • The problem was in the user details. Old data was conflicting with new one. Once old data was deleted from  /_catalogs/users/simple.aspx , the user was correctly added.

SharePoint error: File is locked for editing by ‘domain\username'

Sometimes, when we try to edit a document uploaded on SharePoint, we get a file locked error: “File is locked for editing by ‘domain\username’ “, even though the file has been checked in and no one else is editing the file.
 

Usually a file is locked by WSS when a particular user has ‘checked out’ the file for editing purposes. A write lock is created so that no other user can edit this file simultaneously (except in case of versioning).

When the user checks in the file, the write lock is removed and the file is now available for editing by others.  But sometimes, even if the file has been checked in, it still gives a file lock error. There can be numerous reasons for this such as:

         1.    System crashes while the file is still open.

         2.    File has been closed unexpectedly.

         3.    Check in was not successful.

         4.    Network connection is lost while file is still open.

In most of the cases, the write lock still exist for the file so its gives an editing error.

Below are the few workarounds to resolve this error:

          1.    Check whether the file has been properly checked in or not. If not, refresh the page and try to check in the file again.

          2.    Delete the local copy of the file present in the cache folder of the concerned user account (access to user’s PC required).

          3.     Close all the instances of file type opened in the system. E.g. if the file type is excel, then close all the excel files currently opened.

          4.    Also kill the file type service (excel in this case) using the task manager.


Wait for 10-15 minutes and then try to edit the file. The write lock times out after 10 minutes. Users cannot modify the document during the time when the document is locked. 

Once the write locked times out, the file will be available for editing. If the concerned user is not available or the PC is not accessible, then please refer to this article.

Connecting two Web Parts in SharePoint : SharePoint Tutorial #2

This tutorial describes the step to access data by connecting two different Web Parts in a SharePoint Site. In order to do so, three things should be kept in mind:
  • Provider Web Part (that provides the data)
  • Connection Interface (that provides the connection between two Web Parts)
  • Consumer Web Part ( that accepts the data)
But before we go further, one should be aware of how to create and deploy a web part.

Following are the steps :

Creating a Connection Interface
In this step, we create an interface say ‘CommunicationInterface’.  
In this interface, we define a property ‘ parameter1’ for  providing data.  The no. of properties depends on the no. of parameter to be passed.



//Code Part

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace CommunicationInterface
{
    public interface ICommunicationInterface
    {
        string parameter1 { get; }

    }
}

Once this interface is created, compile it and add its DLL to the Global Assembly Cache (C:\Windows\Assembly) in your  system.





Creating a Provider Web Part
The second step is to create a Provider Web Part to pass the data to the interface.
Create a web part and name it say ‘WP_Provider’.  Add reference of the earlier created ‘CommunicationInterface’ DLL. 
Once the reference is added,  implement the ‘ICommunicationInterface’ to ‘WP_Provider’ class.
Then the connection provider property is added and the reference to the communication Interface is returned.
Implement the property defined in the interface.

//Code Part
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using CommunicationInterface;

namespace WP_Provider
{
   
   public class 
   WP_Provider: Microsoft.SharePoint.WebPartPages.WebPart,ICommunicationInterface
    
   {
        Label nm;
        TextBox tbname;
        Button btn=new Button();
       
        RadioButtonList rb = new RadioButtonList();

       
      // Provides connection provider property for the parameters
      [ConnectionProvider("Parameter1 Provider",
                    "Parameter1 Provider")]
        public ICommunicationInterface ConnectionInterface()
        {
         // this returns a reference to the communication interface
            return this;
        }

        protected string _parameter1 = "";


        // Property defined in Interface is implemented
        public string parameter1
        {
            get { return _parameter1; }
        }
       
       
        public WP_Provider()
        {
       
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();



            //Accessing a particular list items

            SPSite mysitecol = SPContext.Current.Site;
            SPWeb mysite = SPContext.Current.Web;
            SPList mylist = mysite.Lists["UpdateList"];
            SPListItemCollection itemcol = mylist.Items;
           
            foreach (SPListItem itm in itemcol)
            {
                string nm = itm["Company_Id"].ToString();
                rb.Items.Add(nm);

            }

            btn.Text = "Send";
            this.Controls.Add(rb);
            this.Controls.Add(btn);
            btn.Click += new EventHandler(btn_Click);
        }

   public  void btn_Click(object sender, EventArgs e)
        {
            // set connection provider property with required textbox info.
           // this._parameter1 = tbname.Text;
            this._parameter1 = rb.SelectedItem.Text;
        }

    }
}

After completing the code, compile and add the DLL in the Global Assembly Cache (C:\Windows\Assembly).
Create the corresponding ‘dwp’ file and add the SafeControl in the web.config of SharePoint Site.



Creating a Consumer Web Part
The third step is to create a Consumer  Web Part to pass the data to the interface.
Create a web part and name it say ‘WP_Consumer’.  Add reference of the earlier created ‘CommunicationInterface’ DLL. 
Then the connection Consumer property is added and the reference to the communication Interface is retrieved.
From this reference, the parameter that is passed from Provider Web Part is obtained.

//Code
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using CommunicationInterface;

namespace WP_Consumer
{
   
    public class WP_Consumer : Microsoft.SharePoint.WebPartPages.WebPart
    {
       //Label lblTitle;
       Label lblname=new Label();
      

    ///// the string info consumer from custom reciever   //
    ICommunicationInterface connectionInterface = null;

    // The consumer webpart  must define a method that
    // would accept the interface as an parameter
    // and must be decorated with ConnectionConsumer attribute     
    [ConnectionConsumer("Parameter1 Consumer",
                        "Parameter1 Consumer")]
    public void GetConnectionInterface(ICommunicationInterface
                                       _connectionInterface)
    {
        connectionInterface = _connectionInterface;
    }
    ///////////////////////////////////////////////////////// 

    public WP_Consumer()
    {
       
    }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            
            this.Controls.Add(lblname);
           
        }


        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (connectionInterface != null)
            {
                lblname.Text = connectionInterface.parameter1 +
                " is recieved!";
               

             }
            else
            {
                lblname.Text = "nothing is recieved!";
            }
           
        }

     
          
     }

       

  }
}

After completing the code, compile and add the DLL in the Global Assembly Cache. (C:\Windows\Assembly)
Create the corresponding ‘dwp’ file and add the SafeControl in the web.config of SharePoint Site.


Uploading the web parts, Adding the web parts and Connecting the web parts

Once the above steps are completed, upload the web part.
The last and the final step is to connect two web parts. Click on web part edit arrow, then select the connection part.
 
The web parts are connected. Now send and the receive the required data.

Creating a custom web part in SharePoint : SharePoint Tutorial #1

Web part is a server control that is added in SharePoint site to perform some operations on the run such as displaying a list, displaying a web page, adding content to the site, etc.  A web part is added to a web part zone present on the particular web page. 

While there are a number of predefined web parts in SharePoint that can be used out of box; we can create our own custom web parts to perform operations that are not possible with existing web parts.

  Following are the steps to create a custom web part:

1.    Create a class file to write web part code:


a)    Create a new Visual Studio project say ’MyTestWebpart’ and add a class file say ‘MyTestWebpart’ to it.  After this add ‘Windows SharePoint Service’ reference to this project (Right click on project, select add reference, select the required dll under .NET components).

b)    Inherit the web part class(Mircosoft.SharePoint.WebPartPages.WebPart)  and ‘System.Web’ in ‘MyTestWebpart’

c)    Over ride ‘CreateChildControl ‘ and ‘RenderControl’ method in the above class. ‘System.Web’ class has to be inherited as both these method are in ‘System.Web’ Class.

 ‘CreateChildControl’ method is to create and initialize objects. ‘RenderControl’ method is used to render the controls created in the ‘CreateChildControl’ method.
If you are not creating any control and just have to write something using web part, you can use the ‘Render’ method. In this ‘Writer.write’ can be used to display the required info.

using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Text;

namespace MyTestWebpart
{
    public class MyTestWebpart:Microsoft.SharePoint.WebPartPages.WebPart
    {
       

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            writer.Write("Hello World");

        }

    }
}


2.    Sign the project with strong key:

Sign the project with a strong key name. Right click on the project, Select properties, Go to Signing tab. Under Signing tab-> Choose a strong key file->New key.  Enter the new key name say ‘MyTestWebpart’, uncheck the password option and click ok. Save and close.

3.    Deploying the web part dll:

Open Assembly( Type assembly in run and hit enter) and deploy the project dll (in this case ‘MyTestWebpart.dll ) in the Assembly( drag and drop the dll in assembly).

4.    Create a dwp file:  (DWP is the webpart extension to be uploaded in the webpart gallery)

Add an xml file to the project and rename the extension as dwp. Add the required info to below tags.

<?xml version="1.0" encoding="utf-8" ?>
<WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
  <Title>MyTestWebpart</Title>
  <Description>This is a Test Webpart</Description>
  <Assembly>MyTestWebpart, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=9f4da00116c38ec5</Assembly>
  <TypeName>MyTestWebpart.MyTestWebpart</TypeName>
  <!-- Specify initial values for any additional base class or custom properties here. -->
</WebPart>

<Assembly >name should be the name of the project dll. Rest of the assembly details such as version , culture and public key token can be obtain from the properties of the particular dll in the assembly.
<Type name > should be in the form of ‘AssemblyName.ClassName’.

5.    Add Safe Control Entry in application web.config file:

Open the web.config of the application(C:\Inetpub\wwwroot\wss\VirtualDirectories\)  and add a safe control entry for this webpart.

    <SafeControl Assembly="MyTestWebpart, Version=1.0.0.0, Culture=neutral,                   PublicKeyToken=9f4da00116c38ec5"Namespace="MyTestWebpart"
    TypeName="MyTestWebpart" Safe="True" />


6.    Upload the dwp file in the web part gallery:

Click on Site Settings, Select web part under ’Gallaries’.  Next, click on upload and upload the dwp file of this webpart.


7.    Reset IIS/ Application pool


8.    Add the custom web part to required web page

Sunday, February 10, 2013

Session Time Out in SharePoint 2010



We got session time out problem for our sharepoint 2010 application,after googling i was able to increase session time by following the below navigation path

Central Administration -> Application Management -> Manage Web Applications -> Select your Web Application->Click on General Settings Now in Web Page Security Validation category you can set the time as in the below screen shot.

Issues after deploying SharePoint 2010 Designer Reusable Workflow

I got the below issue from one of our colleague in our practise.

Issue
We need to deploy SharePoint designer reusable workflow for approval process to other site collections. We try to get the WSP file from SharePoint Designer using ‘Save as Template’. We try to Import Reusable workflow to Visual Studio using WSP generated above. We try deploy it to other sites and then we are facing the following issues.
1. When we try to Add a workflow to a list, the deployed workflow is listed in All content types. And when we try to select the custom content type we generated, the workflow is not displayed.
2. After adding that workflow to that list, when we initiate that workflow to a list item, it is creating a task. But when we try to edit that task form it is giving page not found error.

Considering this scenario, it would help us if anyone can provide us the deployment approach for a re-usable SharePoint Designer 2010 workflow as a WSP solution package.

After understanding the above,one of my teammate gave the solution as below i.e creating the feature and attaching to workflow association.


Reply
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{

SPWorkflowTemplate workflowTemplate = null; // Workflow template
SPWorkflowAssociation workflowAssociation = null; //Workflow association
SPList historyList = null; // Workflow history list
SPList taskList = null; // Workflow tasks list
SPList list = null;
//Sharepoint List
using (SPSite site = (SPSite)properties.Feature.Parent)
{
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
workflowTemplate = web.WorkflowTemplates.GetTemplateByName(SPPROCWorkflowAssociationConstants.WorkFlowName, System.Globalization.CultureInfo.CurrentCulture);
list = web.Lists[SPPROCWorkflowAssociationConstants.TargetLibrary];
historyList = web.Lists[SPPROCWorkflowAssociationConstants.HistoryList];
taskList = web.Lists[SPPROCWorkflowAssociationConstants.TaskList];
SPContentType ctType = list.ContentTypes[SPPROCWorkflowAssociationConstants.ContentType];
try
{
// Create workflow association
workflowAssociation = SPWorkflowAssociation.CreateListContentTypeAssociation(workflowTemplate, SPPROCWorkflowAssociationConstants.WorkFlowName, taskList, historyList);
// Set workflow parameters
workflowAssociation.AllowManual = true;
workflowAssociation.AutoStartCreate = false;
workflowAssociation.AutoStartChange = false;
// Add workflow association to my list
ctType.WorkflowAssociations.Add(workflowAssociation);
// Enable workflow
workflowAssociation.Enabled = true;
}
catch(Exception exception)
{
SharePointLogger.Local.TraceToDeveloper(exception, exception.Message);
}
finally
{
web.AllowUnsafeUpdates = false;
}
}
}

}

Copy Data from One site to Another Site

Some times we may need to copy the pages from one site to another under the site collection.In SP 2010 its pretty simple,let me explain with clearly.For example there is site 'Latest News',you want to copy the pages from this site to other site called 'Latest News1'.For this navigation is as below

Click on 'Manage Content and structure' which is under 'Site Actions' as below



Through tree view on left side go to the site pages from where you want to copy.Select the pages,under Actions click 'Copy' as below



You will get the dialog box to select the destination as below



After copying it shows the copied page in the destination page as below




Select the destination and click OK.You will get the message as below

Reusable workflows in SharePoint 2010


A long awaited feature has finally come to the SharePoint 2010 and the feature is reusable workflows. In earlier versions we could not create reusable workflows.

We now can create reusable workflow for a content type. Yes, there is one limitation which is we can create a reusable workflows only for content types. So when we add content type to list or library we get the workflow along with it which has logic attached to it.

We will see that in action. First we will create a content type, add that content type to list, then we will create a very simple workflow of course a reusable one which is attached to the content type that we will create and then we will see how that works with workflow in a library.

So go ahead and open SharePoint designer 2010. I am first going to create a site column and content types can only contain site columns.

Click on New site column, I am selecting Choice column and giving name and assigning to a new group and add some data to it.




So now we have site column in our site and we will now create content type.


Now create a new content type.


Now you can find it to the custom group that we gave

Now click on content type and go to its settings page


Click on edit content type columns and then click on add existing site columns from top left


And then select our site column to include the column in the content type.


Keeping the content type settings page open, click on administration web page from where we will associate document template with this content type.


Click on advanced settings, upload a document template. So now we have associated a document template with this content type.

Now is the time when we will add this content type to the existing document library.
Go back to designer, in all lists and library open the library on which you want this content type to be added.

Once the library opens, click on content type settings and add the department category content type to it.


Now we have that document template available in the library. To see that you can open this in browser and then see the library all items page and click on New.


Now open the SharePoint Designer, connect with your site and click on Reusable Workflow.



Select document content type, here we can select the content type on which we would like to attach the workflow to.


Now check the condition, that if the current field is equals to department category and compare that with Marketing then log to history that marketing was selected.


And I have then put if else condition for each department.


Save the workflow and then publish the workflow.

Now it’s time to associate this workflow with the content type. Being on the same workflow settings page, click on associate to content type option from ribbon.

When you click on it, the browser window opens which allows you to associate. Select start this workflow on item adding.


Once you create a document using the template, and when you save it, you can see the workflow has triggered and then completed by saving the right information in the workflow history list.